diff --git a/dbus-vis/ipmi_timeline_vis.js b/dbus-vis/ipmi_timeline_vis.js
new file mode 100644
index 0000000..64af5fc
--- /dev/null
+++ b/dbus-vis/ipmi_timeline_vis.js
@@ -0,0 +1,726 @@
+// This file is about the layout (Preproess() and Group()) of the IPMI time line view.
+// The layout happens according to the following sequence that is very similar to how
+// the layout is done for DBus messages:
+//
+// 1. User clicks any of the checkboxes for the grouping fields (NetFN, CMD)
+// 2. OnGroupByConditionChanged() is called
+// 3. OnGroupByConditionChanged() calls PreProcess() and Group()
+// 4. PreProcess() takes the IPMI messages extracted from the DBus capture
+//    (g_ipmi_parsed_entries), and determines the start time.
+// 5. Group() takes the IPMI messages, and the list of keys, and groups the messages
+//    by the keys. The output is picked up by GenerateTimeLine(), which writes the
+//    timeline data into the Intervals and Titles arrays. The draw loop immediately
+//    picks up the updated Intervals and Titles arrays and draws on the canvas
+//    accordingly.
+
+const {dialog} = require('electron').remote;
+const {fs} = require('file-system');
+const {util} = require('util');
+const {exec} = require('child_process');
+
+// Main view objects
+var ipmi_timeline_view = new IPMITimelineView();
+ipmi_timeline_view.IsTimeDistributionEnabled = true;
+
+var btn_start_capture = document.getElementById('btn_start_capture');
+var select_capture_mode = document.getElementById('select_capture_mode');
+var capture_info = document.getElementById('capture_info');
+
+var radio_open_file = document.getElementById('radio_open_file');
+var radio_capture = document.getElementById('radio_capture');
+var title_open_file = document.getElementById('title_open_file');
+var title_capture = document.getElementById('title_capture');
+
+// Set up Electron-related stuff here; Electron does not allow inlining button
+// events
+document.getElementById('c1').addEventListener(
+    'click', OnGroupByConditionChanged);  // NetFN
+document.getElementById('c2').addEventListener(
+    'click', OnGroupByConditionChanged);  // CMD
+
+// Zoom in button
+document.getElementById('btn_zoom_in').addEventListener('click', function() {
+  ipmi_timeline_view.BeginZoomAnimation(0.5);
+  boost_asio_handler_timeline_view.BeginZoomAnimation(0.5);
+});
+
+// Zoom out button
+document.getElementById('btn_zoom_out').addEventListener('click', function() {
+  ipmi_timeline_view.BeginZoomAnimation(-1);
+  boost_asio_handler_timeline_view.BeginZoomAnimation(-1);
+});
+
+// Pan left button
+document.getElementById('btn_pan_left').addEventListener('click', function() {
+  ipmi_timeline_view.BeginPanScreenAnimaton(-0.5);
+  boost_asio_handler_timeline_view.BeginPanScreenAnimaton(-0.5);
+});
+
+// Pan right button
+document.getElementById('btn_pan_right').addEventListener('click', function() {
+  ipmi_timeline_view.BeginPanScreenAnimaton(0.5);
+  boost_asio_handler_timeline_view.BeginPanScreenAnimaton(0.5);
+});
+
+// Reset zoom button
+document.getElementById('btn_zoom_reset').addEventListener('click', function() {
+  ipmi_timeline_view.BeginSetBoundaryAnimation(
+      RANGE_LEFT_INIT, RANGE_RIGHT_INIT)
+  dbus_timeline_view.BeginSetBoundaryAnimation(
+      RANGE_LEFT_INIT, RANGE_RIGHT_INIT)
+  boost_asio_handler_timeline_view.BeginSetBoundaryAnimation(
+      RANGE_LEFT_INIT, RANGE_RIGHT_INIT)
+})
+
+// Generate replay
+document.getElementById('gen_replay_ipmitool1')
+    .addEventListener('click', function() {
+      GenerateIPMIToolIndividualCommandReplay(HighlightedRequests);
+    });
+document.getElementById('gen_replay_ipmitool2')
+    .addEventListener('click', function() {
+      GenerateIPMIToolExecListReplay(HighlightedRequests);
+    });
+document.getElementById('gen_replay_ipmid_legacy')
+    .addEventListener('click', function() {
+      GenerateBusctlReplayLegacyInterface(HighlightedRequests);
+    });
+document.getElementById('gen_replay_ipmid_new')
+    .addEventListener('click', function() {
+      GenerateBusctlReplayNewInterface(HighlightedRequests);
+    });
+document.getElementById('btn_start_capture')
+    .addEventListener('click', function() {
+      let h = document.getElementById('text_hostname').value;
+      g_capture_state = 'started';
+      StartCapture(h);
+    });
+
+// For capture mode
+document.getElementById('btn_stop_capture')
+    .addEventListener('click', function() {
+      StopCapture();
+    });
+document.getElementById('select_capture_mode')
+    .addEventListener('click', OnCaptureModeChanged);
+radio_open_file.addEventListener('click', OnAppModeChanged);
+radio_capture.addEventListener('click', OnAppModeChanged);
+
+radio_open_file.click();
+
+// App mode: open file or capture
+function OnAppModeChanged() {
+  title_open_file.style.display = 'none';
+  title_capture.style.display = 'none';
+  if (radio_open_file.checked) {
+    title_open_file.style.display = 'block';
+  }
+  if (radio_capture.checked) {
+    title_capture.style.display = 'block';
+  }
+}
+
+// Capture mode: Live capture or staged capture
+function OnCaptureModeChanged() {
+  let x = select_capture_mode;
+  let i = capture_info;
+  let desc = '';
+  switch (x.value) {
+    case 'live':
+      desc = 'Live: read BMC\'s dbus-monitor console output directly';
+      g_capture_mode = 'live';
+      break;
+    case 'staged':
+      desc =
+          'Staged, IPMI only: Store BMC\'s dbus-monitor output in a file and transfer back for display';
+      g_capture_mode = 'staged';
+      break;
+    case 'staged2':
+      desc =
+          'Staged, DBus + IPMI: Store BMC\'s busctl output in a file and transfer back for display';
+      g_capture_mode = 'staged2';
+      break;
+  }
+  i.textContent = desc;
+}
+
+// Data
+var HistoryHistogram = [];
+// var Data_IPMI = []
+
+// =====================
+
+let Intervals = [];
+let Titles = [];
+let HighlightedRequests = [];
+let GroupBy = [];
+let GroupByStr = '';
+
+// (NetFn, Cmd) -> [ Bucket Indexes ]
+// Normalized (0~1) bucket index for the currently highlighted IPMI requests
+let IpmiVizHistHighlighted = {};
+let HistogramThresholds = {};
+
+function IsIntersected(i0, i1) {
+  return (!((i0[1] < i1[0]) || (i0[0] > i1[1])));
+}
+
+function IsIntersectedPixelCoords(i0, i1) {
+  if (i0[1] == undefined || isNaN(i0[1])) {
+    return (Math.abs(i0[0] - i1[0]) < 5);
+  } else {
+    return (IsIntersected(i0, i1));
+  }
+}
+
+var NetFnCmdToDescription = {
+  '6, 1': 'App-GetDeviceId',
+  '6, 3': 'App-WarmReset',
+  '10, 64': 'Storage-GetSelInfo',
+  '10, 35': 'Storage-GetSdr',
+  '4, 32': 'Sensor-GetDeviceSDRInfo',
+  '4, 34': 'Sensor-ReserveDeviceSDRRepo',
+  '4, 47': 'Sensor-GetSensorType',
+  '10, 34': 'Storage-ReserveSdrRepository',
+  '46, 50': 'OEM Extension',
+  '4, 39': 'Sensor-GetSensorThresholds',
+  '4, 45': 'Sensor-GetSensorReading',
+  '10, 67': 'Storage-GetSelEntry',
+  '58, 196': 'IBM_OEM',
+  '10, 32': 'Storage-GetSdrRepositoryInfo',
+  '4, 33': 'Sensor-GetDeviceSDR',
+  '6, 54': 'App-Get BT Interface Capabilities',
+  '10, 17': 'Storage-ReadFruData',
+  '10, 16': 'Storage-GetFruInventoryAreaInfo',
+  '4, 2': 'Sensor-PlatformEvent',
+  '4, 48': 'Sensor-SetSensor',
+  '6, 34': 'App-ResetWatchdogTimer'
+};
+
+const CANVAS_H = document.getElementById('my_canvas_ipmi').height;
+const CANVAS_W = document.getElementById('my_canvas_ipmi').width;
+
+var LowerBoundTime = RANGE_LEFT_INIT;
+var UpperBoundTime = RANGE_RIGHT_INIT;
+var LastTimeLowerBound;
+var LastTimeUpperBound;
+// Dirty flags for determining when to redraw the canvas
+let IsCanvasDirty = true;
+let IsHighlightDirty = false;
+// Animating left and right boundaries
+let IsAnimating = false;
+let LowerBoundTimeTarget = LowerBoundTime;
+let UpperBoundTimeTarget = UpperBoundTime;
+// For keyboard interaction: arrow keys and Shift
+let CurrDeltaX = 0;         // Proportion of Canvas to scroll per frame.
+let CurrDeltaZoom = 0;      // Delta zoom per frame.
+let CurrShiftFlag = false;  // Whether the Shift key is depressed
+
+// TODO: these variables are shared across all views but are now in ipmi_timeline_vis.js, need to move to some other location some time
+const LEFT_MARGIN = 640
+const RIGHT_MARGIN = 1390;
+const LINE_HEIGHT = 15;
+const LINE_SPACING = 17;
+const YBEGIN = 22 + LINE_SPACING;
+const TOP_HORIZONTAL_SCROLLBAR_HEIGHT = YBEGIN - LINE_HEIGHT / 2; // ybegin is the center of the 1st line of the text so need to minus line_height/2
+const BOTTOM_HORIZONTAL_SCROLLBAR_HEIGHT = LINE_HEIGHT;
+const TEXT_Y0 = 3;
+const HISTOGRAM_W = 100, HISTOGRAM_H = LINE_SPACING;
+const HISTOGRAM_X = 270;
+// If some request's time is beyond the right tail, it's considered "too long"
+// If some request's time is below the left tail it's considered "good"
+// const HISTOGRAM_LEFT_TAIL_WIDTH = 0.05, HISTOGRAM_RIGHT_TAIL_WIDTH = 0.05;
+// temporarily disabled for now
+const HISTOGRAM_LEFT_TAIL_WIDTH = -1, HISTOGRAM_RIGHT_TAIL_WIDTH = -1;
+const SCROLL_BAR_WIDTH = 16;
+
+let IpmiVizHistogramImageData = {};  // Image data for rendered histogram
+
+// Input is the data that's completed layout
+// is_free_x:     Should each histogram has its own X range or not
+// num_buckets: # of buckets for histograms
+// theta: top and bottom portion to cut
+function ComputeHistogram(num_buckets = 30, is_free_x = true) {
+  let global_lb = Infinity, global_ub = -Infinity;
+  IpmiVizHistogramImageData = {};
+  // Global minimal and maximal values
+  for (let i = 0; i < Intervals.length; i++) {
+    let interval = Intervals[i];
+    let l = Math.min.apply(Math, interval.map(function(x) {
+      return x[1] - x[0];
+    }));
+    let u = Math.max.apply(Math, interval.map(function(x) {
+      return x[1] - x[0];
+    }));
+    global_lb = Math.min(l, global_lb);
+    global_ub = Math.max(u, global_ub);
+  }
+
+  HistoryHistogram = [];
+  for (let i = 0; i < Intervals.length; i++) {
+    let interval = Intervals[i];
+    let lb = global_lb, ub = global_ub;
+    if (is_free_x == true) {
+      lb = Math.min.apply(Math, interval.map(function(x) {
+        return x[1] - x[0];
+      }));
+      ub = Math.max.apply(Math, interval.map(function(x) {
+        return x[1] - x[0];
+      }));
+    }
+    const EPS = 1e-2;
+    if (lb == ub) ub = lb + EPS;
+    let line = [lb * 1000000, ub * 1000000];  // to usec
+    let buckets = [];
+    for (let j = 0; j < num_buckets; j++) buckets.push(0);
+    for (let j = 0; j < interval.length; j++) {
+      let t = interval[j][1] - interval[j][0];
+      let bucket_idx = parseInt(t / ((ub - lb) / num_buckets));
+      buckets[bucket_idx]++;
+    }
+    line.push(buckets);
+    HistoryHistogram[Titles[i].title] = line;
+  }
+}
+
+function Preprocess(data) {
+  preprocessed = [];
+  let StartingUsec_IPMI;
+
+  if (g_StartingSec == undefined) {
+    StartingUsec_IPMI = undefined;
+  } else {
+    StartingUsec_IPMI = g_StartingSec * 1000000;
+  }
+
+  for (let i = 0; i < data.length; i++) {
+    let entry = data[i].slice();
+    let lb = entry[2], ub = entry[3];
+
+    // Only when IPMI view is present (i.e. no DBus pcap is loaded)
+    if (i == 0 && StartingUsec_IPMI == undefined) {
+      StartingUsec_IPMI = lb;
+    }
+
+    entry[2] = lb - StartingUsec_IPMI;
+    entry[3] = ub - StartingUsec_IPMI;
+    preprocessed.push(entry);
+  }
+  return preprocessed;
+}
+
+let SHOW_BLOB_DETAILS = true;
+function Group(data, groupBy) {
+  let grouped = {};
+
+  // If has netfn and cmd: use "NetFN, CMD" as key
+  // Otherwise, use "NetFN" as key
+  // This distinction is made if the user chooses to label operation on each
+  // blob individually
+
+  // Key:   blob name
+  // Value: the commands that operate on the particular blob
+  let sid2blobid = {}
+
+  for (let n = 0; n < data.length; n++) {
+    const p = data[n];
+    const netfn = p[0], cmd = p[1], req = p[4], res = p[5];
+    if (netfn == 46 && cmd == 128) {
+      const oen = req[0] + req[1] * 256 + req[2] * 65536;
+      if (oen == 0xc2cf) {  // Blob operations
+        const blobcmd =
+            req[3];  // Refer to https://github.com/openbmc/phosphor-ipmi-blobs
+
+        // The IPMI blob commands are visible on DBus, another WIP command-line tool that
+        // utilizes this fact to show information about blobs can be found here:
+        // https://gerrit.openbmc-project.xyz/c/openbmc/openbmc-tools/+/41451
+
+        let sid, blobid;
+
+        // layout of req
+        //  0  1  2   3  4  5   6  7  8  9  10 ...
+        // CF C2 00 CMD [CRC ] [ other stuff  ]
+
+        // layout of res
+        //  0  1  2   3  4   5   6  7  8  ...
+        // CF C2 00  [CRC ] [other stuff]
+
+        // Determining blob id and session ID
+        switch (blobcmd) {
+          case 3:
+          case 4:
+          case 5:
+          case 6:
+          case 9:
+          case 10: {
+            const sid = req[6] + req[7] * 256;
+            blobid = sid2blobid[sid];
+            if (blobid != undefined) {
+              p.key = blobid;
+            }
+            break;
+          }
+          case 7:
+          case 8: {
+            blobid = '';
+            for (let i = 6; i < req.length; i++) {
+              blobid += String.fromCharCode(req[i]);
+            }
+            break;
+          }
+        }
+
+        switch (blobcmd) {
+          case 2: {  // open
+            blobid = '';
+            for (let i = 8; i < req.length; i++) {
+              if (req[i] == 0)
+                break;
+              else
+                blobid += String.fromCharCode(req[i]);
+            }
+            p.key = blobid;
+            sid = res[5] + res[6] * 256;  // session_id
+            sid2blobid[sid] = blobid;
+            break;
+          }
+          case 3: {  // Read
+
+            break;
+          }
+          case 4: {  // Write
+            const offset =
+                req[8] + req[9] * 256 + req[10] * 65536 + req[11] * 16777216;
+            p.offset = offset;
+            break;
+          }
+          case 5: {  // Commit
+            break;
+          }
+          case 6: {  // Close
+            break;
+          }
+        }
+      }
+    }
+  }
+
+  const idxes = {'NetFN': 0, 'CMD': 1};
+
+  //
+  for (let n = 0; n < data.length; n++) {
+    const p = data[n];
+    let key = '';
+    if (p.key != undefined)
+      key = p.key;
+    else if (p[0] != '' && p[1] != '') {
+      for (let i = 0; i < groupBy.length; i++) {
+        if (i > 0) {
+          key += ', ';
+        }
+        key += p[idxes[groupBy[i]]];
+      }
+    }
+
+    if (grouped[key] == undefined) {
+      grouped[key] = [];
+    }
+    grouped[key].push(p);
+  }
+
+  return grouped;
+}
+
+function GenerateTimeLine(grouped) {
+  const keys = Object.keys(grouped);
+  let sortedKeys = keys.slice();
+  // If NetFN and CMD are both selected, sort by NetFN then CMD
+  // In this case, all "keys" are string-encoded integer pairs
+  if (keys.length > 0 && ipmi_timeline_view.GroupBy.length == 2) {
+    sortedKeys = sortedKeys.sort(function(a, b) {
+      a = a.split(',');
+      b = b.split(',');
+      if (a.length == 2 && b.length == 2) {
+        let aa = parseInt(a[0]) * 256 + parseInt(a[1]);
+        let bb = parseInt(b[0]) * 256 + parseInt(b[1]);
+        return aa < bb ? -1 : (aa > bb ? 1 : 0);
+      } else {
+        return a < b ? -1 : (a > b ? 1 : 0);
+      }
+    });
+  }
+
+  Intervals = [];
+  Titles = [];
+  for (let i = 0; i < sortedKeys.length; i++) {
+    Titles.push({"header":false, "title":sortedKeys[i], "intervals_idxes":[i]});
+    line = [];
+    for (let j = 0; j < grouped[sortedKeys[i]].length; j++) {
+      let entry = grouped[sortedKeys[i]][j];
+      // Lower bound, Upper bound, and a reference to the original request
+      line.push([
+        parseFloat(entry[2]) / 1000000, parseFloat(entry[3]) / 1000000, entry,
+        'ok', 0
+      ]);
+    }
+    Intervals.push(line);
+  }
+
+  ipmi_timeline_view.Intervals = Intervals.slice();
+  ipmi_timeline_view.Titles = Titles.slice();
+  ipmi_timeline_view.LayoutForOverlappingIntervals();
+}
+
+function OnGroupByConditionChanged() {
+  const tags = ['c1', 'c2'];
+  const v = ipmi_timeline_view;
+  v.GroupBy = [];
+  v.GroupByStr = '';
+  for (let i = 0; i < tags.length; i++) {
+    let cb = document.getElementById(tags[i]);
+    if (cb.checked) {
+      v.GroupBy.push(cb.value);
+      if (v.GroupByStr.length > 0) {
+        v.GroupByStr += ', ';
+      }
+      v.GroupByStr += cb.value;
+    }
+  }
+  let preproc = Preprocess(Data_IPMI);
+  grouped = Group(preproc, v.GroupBy);
+  GenerateTimeLine(grouped);
+
+  IsCanvasDirty = true;
+  ipmi_timeline_view.IsCanvasDirty = true;
+}
+
+function MapXCoord(x, left_margin, right_margin, rl, rr) {
+  let ret = left_margin + (x - rl) / (rr - rl) * (right_margin - left_margin);
+  if (ret < left_margin) {
+    ret = left_margin;
+  } else if (ret > right_margin) {
+    ret = right_margin;
+  }
+  return ret;
+}
+
+function draw_timeline(ctx) {
+  ipmi_timeline_view.Render(ctx);
+}
+
+
+window.addEventListener('keydown', function() {
+  if (event.keyCode == 37) {  // Left Arrow
+    ipmi_timeline_view.CurrDeltaX = -0.004;
+    dbus_timeline_view.CurrDeltaX = -0.004;
+  } else if (event.keyCode == 39) {  // Right arrow
+    ipmi_timeline_view.CurrDeltaX = 0.004;
+    dbus_timeline_view.CurrDeltaX = 0.004;
+  } else if (event.keyCode == 16) {  // Shift
+    ipmi_timeline_view.CurrShiftFlag = true;
+    dbus_timeline_view.CurrShiftFlag = true;
+  } else if (event.keyCode == 38) {  // Up arrow
+    ipmi_timeline_view.CurrDeltaZoom = 0.01;
+    dbus_timeline_view.CurrDeltaZoom = 0.01;
+  } else if (event.keyCode == 40) {  // Down arrow
+    ipmi_timeline_view.CurrDeltaZoom = -0.01;
+    dbus_timeline_view.CurrDeltaZoom = -0.01;
+  }
+});
+
+window.addEventListener('keyup', function() {
+  if (event.keyCode == 37 || event.keyCode == 39) {
+    ipmi_timeline_view.CurrDeltaX = 0;
+    dbus_timeline_view.CurrDeltaX = 0;
+  } else if (event.keyCode == 16) {
+    ipmi_timeline_view.CurrShiftFlag = false;
+    dbus_timeline_view.CurrShiftFlag = false;
+  } else if (event.keyCode == 38 || event.keyCode == 40) {
+    ipmi_timeline_view.CurrDeltaZoom = 0;
+    dbus_timeline_view.CurrDeltaZoom = 0;
+  }
+});
+
+function MouseXToTimestamp(x) {
+  let ret = (x - LEFT_MARGIN) / (RIGHT_MARGIN - LEFT_MARGIN) *
+          (UpperBoundTime - LowerBoundTime) +
+      LowerBoundTime;
+  ret = Math.max(ret, LowerBoundTime);
+  ret = Math.min(ret, UpperBoundTime);
+  return ret;
+}
+
+let HighlightedRegion = {t0: -999, t1: -999};
+
+function IsHighlighted() {
+  return (HighlightedRegion.t0 != -999 && HighlightedRegion.t1 != -999);
+}
+
+function Unhighlight() {
+  HighlightedRegion.t0 = -999;
+  HighlightedRegion.t1 = -999;
+}
+
+function UnhighlightIfEmpty() {
+  if (HighlightedRegion.t0 == HighlightedRegion.t1) {
+    Unhighlight();
+    return true;
+  }
+  return false;
+}
+
+let MouseState = {
+  hovered: true,
+  pressed: false,
+  x: 0,
+  y: 0,
+  hoveredVisibleLineIndex: -999,
+  hoveredSide: undefined
+};
+let Canvas = document.getElementById('my_canvas_ipmi');
+
+Canvas.onmousemove = function(event) {
+  const v = ipmi_timeline_view;
+  v.MouseState.x = event.pageX - this.offsetLeft;
+  v.MouseState.y = event.pageY - this.offsetTop;
+  if (v.MouseState.pressed == true) {  // Update highlighted area
+    v.HighlightedRegion.t1 = v.MouseXToTimestamp(v.MouseState.x);
+  }
+  v.OnMouseMove();
+  v.IsCanvasDirty = true;
+
+  v.linked_views.forEach(function(u) {
+    u.MouseState.x = event.pageX - Canvas.offsetLeft;
+    u.MouseState.y = 0;                  // Do not highlight any entry
+    if (u.MouseState.pressed == true) {  // Update highlighted area
+      u.HighlightedRegion.t1 = u.MouseXToTimestamp(u.MouseState.x);
+    }
+    u.OnMouseMove();
+    u.IsCanvasDirty = true;
+  });
+};
+
+Canvas.onmouseover = function() {
+  ipmi_timeline_view.OnMouseMove();
+};
+
+Canvas.onmouseleave = function() {
+  ipmi_timeline_view.OnMouseLeave();
+};
+
+Canvas.onmousedown = function(event) {
+  if (event.button == 0) {  // Left mouse button
+    ipmi_timeline_view.OnMouseDown();
+  }
+};
+
+Canvas.onmouseup = function(event) {
+  if (event.button == 0) {
+    ipmi_timeline_view.OnMouseUp();
+    // page-specific, not view-specific
+    let hint = document.getElementById('highlight_hint');
+    if (ipmi_timeline_view.UnhighlightIfEmpty()) {
+      hint.style.display = 'none';
+    } else {
+      hint.style.display = 'block';
+    }
+  }
+};
+
+Canvas.onwheel = function(event) {
+  ipmi_timeline_view.OnMouseWheel(event);
+};
+
+// This function is not specific to TimelineView so putting it here
+function OnHighlightedChanged(reqs) {
+  let x = document.getElementById('ipmi_replay');
+  let i = document.getElementById('ipmi_replay_output');
+  let cnt = document.getElementById('highlight_count');
+  cnt.innerHTML = '' + reqs.length;
+  i.style.display = 'none';
+  if (reqs.length > 0) {
+    x.style.display = 'block';
+  } else
+    x.style.display = 'none';
+  let o = document.getElementById('ipmi_replay_output');
+  o.style.display = 'none';
+  o.textContent = '';
+}
+
+function ToHexString(bytes, prefix, sep) {
+  let ret = '';
+  for (let i = 0; i < bytes.length; i++) {
+    if (i > 0) {
+      ret += sep;
+    }
+    ret += prefix + bytes[i].toString(16);
+  }
+  return ret;
+}
+
+function ToASCIIString(bytes) {
+  ret = '';
+  for (let i = 0; i < bytes.length; i++) {
+    ret = ret + String.fromCharCode(bytes[i]);
+  }
+  return ret;
+}
+
+function ShowReplayOutputs(x, ncols) {
+  let o = document.getElementById('ipmi_replay_output');
+  o.cols = ncols;
+  o.style.display = 'block';
+  o.textContent = x;
+}
+
+function GenerateIPMIToolIndividualCommandReplay(reqs) {
+  let x = '';
+  for (let i = 0; i < reqs.length; i++) {
+    let req = reqs[i];
+    // [0]: NetFN, [1]: cmd, [4]: payload
+    // NetFN and cmd are DECIMAL while payload is HEXADECIMAL.
+    x = x + 'ipmitool raw ' + req[0] + ' ' + req[1] + ' ' +
+        ToHexString(req[4], '0x', ' ') + '\n';
+  }
+  ShowReplayOutputs(x, 80);
+}
+
+function GenerateIPMIToolExecListReplay(reqs) {
+  console.log(reqs.length);
+  let x = '';
+  for (let i = 0; i < reqs.length; i++) {
+    let req = reqs[i];
+    x = x + 'raw ' +
+        ToHexString([req[0]].concat([req[1]]).concat(req[4]), '0x', ' ') + '\n';
+  }
+  ShowReplayOutputs(x, 80);
+}
+
+function GenerateBusctlReplayLegacyInterface(reqs) {
+  console.log(reqs.length);
+  let serial = 0;
+  let x = '';
+  for (let i = 0; i < reqs.length; i++) {
+    let req = reqs[i];
+    x = x +
+        'busctl --system emit  /org/openbmc/HostIpmi/1 org.openbmc.HostIpmi ReceivedMessage yyyyay ';
+    x = x + serial + ' ' + req[0] + ' 0 ' + req[1] + ' ' + req[4].length + ' ' +
+        ToHexString(req[4], '0x', ' ') + '\n';
+    serial = (serial + 1) % 256;
+  }
+  ShowReplayOutputs(x, 120);
+}
+
+function GenerateBusctlReplayNewInterface(reqs) {
+  console.log(reqs.length);
+  let x = '';
+  for (let i = 0; i < reqs.length; i++) {
+    let req = reqs[i];
+    x = x +
+        'busctl --system call xyz.openbmc_project.Ipmi.Host /xyz/openbmc_project/Ipmi xyz.openbmc_project.Ipmi.Server execute yyyaya{sv} ';
+    x = x + req[0] + ' 0 ' + req[1] + ' ' + req[4].length + ' ' +
+        ToHexString(req[4], '0x', ' ');
+    +' 0\n';
+  }
+  ShowReplayOutputs(x, 150);
+}
