From 6ba3993d4908eac19b260d82f31aac593e2bdaee Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Mon, 8 Oct 2012 09:55:38 +0200 Subject: cesar/common/tools/traceviewer: add medium analysis, closes #3428 --- cesar/common/tools/traceviewer/analyse/__init__.py | 0 cesar/common/tools/traceviewer/analyse/medium.py | 118 +++++++++++++++++++++ cesar/common/tools/traceviewer/command.py | 5 + cesar/common/tools/traceviewer/trace_analyse.py | 9 ++ 4 files changed, 132 insertions(+) create mode 100644 cesar/common/tools/traceviewer/analyse/__init__.py create mode 100644 cesar/common/tools/traceviewer/analyse/medium.py create mode 100644 cesar/common/tools/traceviewer/trace_analyse.py (limited to 'cesar/common') diff --git a/cesar/common/tools/traceviewer/analyse/__init__.py b/cesar/common/tools/traceviewer/analyse/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cesar/common/tools/traceviewer/analyse/medium.py b/cesar/common/tools/traceviewer/analyse/medium.py new file mode 100644 index 0000000000..bc379f8340 --- /dev/null +++ b/cesar/common/tools/traceviewer/analyse/medium.py @@ -0,0 +1,118 @@ +"""Analyse medium usage.""" +import re +import traceviewer.trace as trace + +DEFAULT_MODE = 2 + +RX_COLOR = '#00c0ff' +TX_COLOR = '#ffc000' + +MAC_PREAMBLE_TCK = 3840 / 3 +MAC_PREAMBLE_HYBRID_TCK = 3456 / 3 +MAC_FC_10_TCK = 2892 / 3 +MAC_FC_AV_TCK = 4446 / 3 +MAC_DX417_TCK = 3489 / 3 +MAC_DX567_TCK = 3639 / 3 +MAC_DX3534_TCK = 6606 / 3 + +pre_fcs_tck = [ + MAC_PREAMBLE_HYBRID_TCK + MAC_FC_10_TCK + MAC_FC_AV_TCK, + MAC_PREAMBLE_HYBRID_TCK + MAC_FC_10_TCK + MAC_FC_AV_TCK * 2, + MAC_PREAMBLE_TCK + MAC_FC_AV_TCK, + MAC_PREAMBLE_TCK + MAC_FC_AV_TCK * 2, + ] +dx_tck = [ MAC_DX417_TCK, MAC_DX567_TCK, MAC_DX3534_TCK ] + +def pre_fcs_data_tck (mode, gil, symb_nb): + """Compute frame occupation on medium.""" + if symb_nb is None: + symb_nb = 0 + if symb_nb <= 2: + return pre_fcs_tck[mode] + MAC_DX567_TCK * symb_nb + else: + return (pre_fcs_tck[mode] + MAC_DX567_TCK * 2 + + dx_tck[gil] * (symb_nb - 2)) + +def to_int (*args): + """Convert to integer if not None.""" + return tuple (int (i) if i is not None else None + for i in args) + +rx_param_re = re.compile (r'rx param mode=(\d+)') +rx_fc_re = re.compile (r'rx fc cb rx_date=(0x[0-9a-f]+)') +rx_prepare_re = re.compile (r'rx (?:prepare short' + + r'|(?:prepare|sound) .* gil=(\d+) symb_nb=(\d+))') +tx_param_re = re.compile (r'tx (?:param short|param|sound) mode=(\d+)' + + r'(?:.* gil=(\d+) symb_nb=(\d+))?') +tx_frame_re = re.compile (r'tx frame date=(0x[0-9a-f]+) want_conf=(true|false)') +tx_access_conf_re = re.compile (r'access conf cb') + +def analyse (bundle): + # Find phy traces. + phy = None + for t in bundle.traces: + name = t.name.split (': ')[-1] + if name == 'phy': + phy = t + break + if phy is None: + return + # Populate a new trace with medium usage. + medium = trace.Trace (bundle.name + ': medium') + mode = DEFAULT_MODE + last_rx, last_tx = None, None + tx_param = None + for t in phy.trace: + # RX. + m = rx_param_re.match (t.text) + if m: + mode = int (m.group (1)) + next + m = rx_fc_re.match (t.text) + if m: + date = long (m.group (1), 0) + last_rx = trace.TraceEntry (date, 0, 'RX') + last_rx.view_text = 'RX' + last_rx.view_attr = RX_COLOR + medium.trace.append (last_rx) + next + if last_rx is not None: + m = rx_prepare_re.match (t.text) + if m: + gil, symb_nb = to_int (*m.groups ()) + last_rx.duration = pre_fcs_data_tck (mode, gil, symb_nb) + last_rx.text = 'RX end_date=0x%08x' % (last_rx.date + + last_rx.duration) + last_rx = None + next + # TX. + m = tx_param_re.match (t.text) + if m: + mode = int (m.group (1)) + tx_param = to_int (m.group (2), m.group (3)) + next + if tx_param is not None: + m = tx_frame_re.match (t.text) + if m: + date = long (m.group (1), 0) + want_conf = m.group (2) == 'true' + duration = pre_fcs_data_tck (mode, *tx_param) + text = 'TX end_date=0x%08x' % (date + duration) + t = trace.TraceEntry (date, duration, text) + t.view_text = 'TX' + t.view_attr = TX_COLOR + if want_conf: + last_tx = t + else: + medium.trace.append (t) + tx_param = None + next + if last_tx is not None: + m = tx_access_conf_re.match (t.text) + if m: + medium.trace.append (last_tx) + last_tx = None + next + # Add trace unless empty. + if medium.trace: + bundle.traces.insert (0, medium) diff --git a/cesar/common/tools/traceviewer/command.py b/cesar/common/tools/traceviewer/command.py index 655e241846..8ba06bd274 100644 --- a/cesar/common/tools/traceviewer/command.py +++ b/cesar/common/tools/traceviewer/command.py @@ -2,6 +2,7 @@ from gui import Gui from trace import read_traces_from_dump from trace_bundle import read_bundles_from_dump from trace_annotate import annotate +from trace_analyse import analyse, DEFAULT_ANALYSES from optparse import OptionParser import gzip @@ -26,6 +27,9 @@ def run (): help='include only trace matching REGEX', metavar='REGEX') opt.add_option ('-x', '--exclude', action = 'append', default = [ ], help='exclude named TRACE', metavar='TRACE') + opt.add_option ('-a', '--analyse', action = 'append', + default = DEFAULT_ANALYSES, + help='add analysis module', metavar='MODULE') (options, args) = opt.parse_args () # Read traces. traces = [ ] @@ -35,6 +39,7 @@ def run (): for f in options.bundle + args: bs = read_bundles_from_dump (f, open_file (f)) for b in bs: + analyse (b, options.analyse) traces.extend (b.traces) # Filter traces. traces = [ t for t in traces if t.name not in options.exclude ] diff --git a/cesar/common/tools/traceviewer/trace_analyse.py b/cesar/common/tools/traceviewer/trace_analyse.py new file mode 100644 index 0000000000..94c4590383 --- /dev/null +++ b/cesar/common/tools/traceviewer/trace_analyse.py @@ -0,0 +1,9 @@ +"""Import module to analyse a trace bundle.""" + +DEFAULT_ANALYSES = [ 'medium' ] + +def analyse (bundle, analyses): + for m in analyses: + mod = __import__ ('traceviewer.analyse.' + m, + globals (), locals (), [ 'analyse' ]) + mod.analyse (bundle) -- cgit v1.2.3