[PATCH] osmo-bts[master]: Add tools to check DTX operation

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Max gerrit-no-reply at lists.osmocom.org
Fri Oct 21 14:35:09 UTC 2016


Review at  https://gerrit.osmocom.org/1143

Add tools to check DTX operation

* dsp.sh can parse superfemto-compatible DSP log output to properly sort
records into MT/MO and DL/UL parts
* dtx_check.gawk can process output of dsp.sh and check for common
  scheduling errors

Change-Id: Ib1c70c4543b24c2a05a7df8eec5ce3f4eda2c02e
Related: OS#1801
---
A contrib/dsp.sh
A contrib/dtx_check.gawk
2 files changed, 163 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/43/1143/1

diff --git a/contrib/dsp.sh b/contrib/dsp.sh
new file mode 100755
index 0000000..8be20bf
--- /dev/null
+++ b/contrib/dsp.sh
@@ -0,0 +1,99 @@
+#!/bin/sh
+
+# Split common DSP call log file into 4 separate call leg files (MO/MT & DL/UL) with events in format "FN EVENT_TYPE":
+# MO Mobile Originated
+# MT Mobile Terminated
+# DL DownLink (BTS -> L1)
+# UL UpLink (L1 -> BTS)
+
+if [ -z $1 ]; then
+    echo "expecting DSP log file name as parameter"
+    exit 1
+fi
+
+# MO handle appear 1st in the logs
+MO=$(grep 'h=' $1 | head -n 1 | cut -f2 -d',' | cut -f2 -d= | cut -f1 -d']')
+
+# direction markers:
+DLST="_CodeBurst"
+ULST="_DecodeAndIdentify"
+
+# DL sed filters:
+D_EMP='s/ Empty frame request/EMPTY/'
+D_FAC='s/ Coding a FACCH frame!/FACCH/'
+D_FST='s/ Coding a RTP SID First frame !!/FIRST/'
+D_UPD='s/ Coding a RTP SID Update frame !!/UPDATE/'
+D_SPE='s/ Coding a RTP Speech frame !!/SPEECH/'
+D_ONS='s/ Coding a Onset frame !!/ONSET/'
+D_FO1='s/ A speech frame is following a NoData or SID First without an Onset./FORCED_FIRST/'
+D_FO2='s/ A speech frame is following a NoData without an Onset./FORCED_NODATA/'
+
+# UL sed filters:
+U_NOD='s/ It is a No Data frame !!/NODATA/'
+U_ONS='s/ It is an ONSET frame !!/ONSET/'
+U_UPD='s/ It is a SID UPDATE frame !!/UPDATE/'
+U_FST='s/ It is a SID FIRST frame !!/FIRST/'
+U_SPE='s/ It is a SPEECH frame !!/SPEECH/'
+
+DL () { # filter downlink-related entries
+    cat $1 | grep $DLST > $1.DL.tmp
+}
+
+UL () { # uplink does not require special fix
+    cat $1 | grep $ULST > $1.UL.tmp.fix
+}
+
+DL $1
+UL $1
+
+FIX() { # add MO/MT marker from preceding line to inserted ONSETs so filtering works as expected
+    cat $1.DL.tmp | awk 'BEGIN{ FS="h="; H="" } { if (NF > 1) { H = $2; print $1 "h=" $2 } else { print $1 ", h=" H } }' > $1.DL.tmp.fix
+}
+
+FIX $1
+
+MO() { # filter MO call DL or UL logs
+    grep "h=$MO" $1.tmp.fix > $1.MO.raw
+}
+
+MT() { # filter MT call DL or UL logs
+    grep -v "h=$MO" $1.tmp.fix > $1.MT.raw
+}
+
+MO $1.DL
+MT $1.DL
+MO $1.UL
+MT $1.UL
+
+PREP() { # prepare logs for reformatting
+    cat $1.raw | cut -f2 -d')' | cut -f1 -d',' | cut -f2 -d'>' | sed 's/\[u32Fn/fn/' | sed 's/fn = /fn=/' | sed 's/fn=//' | sed 's/\[Fn=//' | sed 's/ An Onset will be inserted.//' > $1.tmp1
+}
+
+PREP "$1.DL.MT"
+PREP "$1.DL.MO"
+PREP "$1.UL.MT"
+PREP "$1.UL.MO"
+
+RD() { # reformat DL logs for consistency checks
+    cat $1.tmp1 | sed "$D_FST" | sed "$D_SPE" | sed "$D_UPD" | sed "$D_ONS" | sed "$D_EMP" | sed "$D_FAC" | sed "$D_FO1" | sed "$D_FO2" > $1.tmp2
+}
+
+RU() { # reformat UL logs for consistency checks
+    cat $1.tmp1 | sed "$U_FST" | sed "$U_SPE" | sed "$U_UPD" | sed "$U_ONS" | sed "$U_NOD" > $1.tmp2
+}
+
+RD "$1.DL.MT"
+RD "$1.DL.MO"
+RU "$1.UL.MT"
+RU "$1.UL.MO"
+
+SW() { # swap fields
+    cat $1.tmp2 | awk '{ print $2, $1 }' > $1
+}
+
+SW "$1.DL.MT"
+SW "$1.DL.MO"
+SW "$1.UL.MT"
+SW "$1.UL.MO"
+
+rm $1.*.tmp*
diff --git a/contrib/dtx_check.gawk b/contrib/dtx_check.gawk
new file mode 100755
index 0000000..a8cb32c
--- /dev/null
+++ b/contrib/dtx_check.gawk
@@ -0,0 +1,64 @@
+#!/usr/bin/gawk -f
+
+# Expected input format: FN TYPE
+
+BEGIN {
+	DELTA = 0
+	ERR = 0
+	FN = 0
+	TYPE = ""
+	CHK = ""
+	U_MAX = 8 * 20 + 120 / 26
+	U_MIN = 8 * 20 - 120 / 26
+	F_MAX = 3 * 20 + 120 / 26
+	F_MIN = 3 * 20 - 120 / 26
+}
+
+{
+	if (NR > 1) { # we have data from previous record to compare to
+		DELTA = ($1 - FN) * 120 / 26
+		CHK = "OK"
+		if ("UPDATE" == TYPE || "FIRST" == TYPE) { # check for missing ONSET:
+			if ("FACCH" == $2 || "SPEECH" == $2) {
+				CHK = "FAIL: missing ONSET"
+				ERR++
+			}
+		}
+		if ("OK" == CHK) { # check inter-SID distances:
+			if ("UPDATE" == TYPE) {
+				if (DELTA > U_MAX) {
+					CHK = "FAIL: delta (" $1 - FN "fn) from previous SID UPDATE (@" FN ") too big " DELTA "ms > " U_MAX "ms"
+					ERR++
+				}
+				if ("UPDATE" == $2) {
+					if (DELTA < U_MIN) {
+						CHK = "FAIL: delta (" $1 - FN "fn) from previous SID UPDATE (@" FN ") too small " DELTA "ms < " U_MIN "ms"
+						ERR++
+					}
+				}
+			}
+			if ("FIRST" == TYPE) {
+				if (DELTA > F_MAX) {
+					CHK = "FAIL: delta (" $1 - FN "fn) from previous SID FIRST (@" FN ") too big " DELTA "ms > " F_MAX "ms"
+					ERR++
+				}
+				if ("UPDATE" == $2) {
+					if (DELTA < F_MIN) {
+						CHK = "FAIL: delta (" $1 - FN "fn) from previous SID UPDATE (@" FN ") too small " DELTA "ms < " F_MIN "ms"
+						ERR++
+					}
+				}
+			}
+		}
+		# FIXME: FACCH-specific checks?
+	}
+	print $1, $2, CHK, TYPE, DELTA
+	if ($2 != "EMPTY") { # skip over EMPTY records
+		TYPE = $2
+		FN = $1
+	}
+}
+
+END {
+	print "check completed: found " ERR " errors in " NR " records"
+}

-- 
To view, visit https://gerrit.osmocom.org/1143
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib1c70c4543b24c2a05a7df8eec5ce3f4eda2c02e
Gerrit-PatchSet: 1
Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Owner: Max <msuraev at sysmocom.de>



More information about the gerrit-log mailing list