<p>Harald Welte <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/11241">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Jenkins Builder: Verified
Harald Welte: Looks good to me, approved
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Add a TTCN3 module for IPA protocol testing<br><br>This new module allows us to test IPA code in libosmocore<br>and libosmo-netif. Currently only one test is implemented,<br>which sends a chopped IPA ping message and expects to receive<br>an IPA pong.<br><br>The system under test is any IPA speaker on any TCP port.<br>Any test suite may call parametrized functions to create<br>an IPA testing component and run a particular test.<br>So far, one such test has been added to the BSC_Tests suite.<br><br>Change-Id: I246a405414e36a44dc1e308692faab8bf04da0e6<br>Related: OS#2010<br>---<br>M bsc/BSC_Tests.cfg<br>M bsc/BSC_Tests.ttcn<br>M bsc/gen_links.sh<br>A library/IPA_Testing.ttcn<br>4 files changed, 183 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/bsc/BSC_Tests.cfg b/bsc/BSC_Tests.cfg</span><br><span>index 175654a..4e6c40e 100644</span><br><span>--- a/bsc/BSC_Tests.cfg</span><br><span>+++ b/bsc/BSC_Tests.cfg</span><br><span>@@ -74,3 +74,4 @@</span><br><span> #BSC_Tests.TC_err_82_short_msg</span><br><span> #BSC_Tests.TC_err_84_unknown_msg</span><br><span> #BSC_Tests.TC_ho_int</span><br><span style="color: hsl(120, 100%, 40%);">+#BSC_Tests.TC_chopped_ipa_ping</span><br><span>diff --git a/bsc/BSC_Tests.ttcn b/bsc/BSC_Tests.ttcn</span><br><span>index 4a34310..28ade1e 100644</span><br><span>--- a/bsc/BSC_Tests.ttcn</span><br><span>+++ b/bsc/BSC_Tests.ttcn</span><br><span>@@ -30,6 +30,7 @@</span><br><span> import from IPA_Emulation all;</span><br><span> import from IPA_CodecPort all;</span><br><span> import from IPA_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from IPA_Testing all;</span><br><span> import from RSL_Types all;</span><br><span> import from RSL_Emulation all;</span><br><span> import from MGCP_Emulation all;</span><br><span>@@ -2729,6 +2730,14 @@</span><br><span> setverdict(pass);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_chopped_ipa_ping() runs on test_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port</span><br><span style="color: hsl(120, 100%, 40%);">+ /* TOOD: This port is failing: mp_bsc_ctrl_port */ };</span><br><span style="color: hsl(120, 100%, 40%);">+ for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Dyn PDCH todo:</span><br><span> * activate OSMO as TCH/F</span><br><span> * activate OSMO as TCH/H</span><br><span>@@ -2836,6 +2845,8 @@</span><br><span> execute( TC_dyn_pdch_osmo_act_deact() );</span><br><span> execute( TC_dyn_pdch_osmo_act_nack() );</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ execute( TC_chopped_ipa_ping() );</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* at bottom as they might crash OsmoBSC before OS#3182 is fixed */</span><br><span> execute( TC_early_conn_fail() );</span><br><span> execute( TC_late_conn_fail() );</span><br><span>diff --git a/bsc/gen_links.sh b/bsc/gen_links.sh</span><br><span>index 3e27cb1..88983d7 100755</span><br><span>--- a/bsc/gen_links.sh</span><br><span>+++ b/bsc/gen_links.sh</span><br><span>@@ -67,7 +67,7 @@</span><br><span> gen_links $DIR $FILES</span><br><span> </span><br><span> DIR=../library</span><br><span style="color: hsl(0, 100%, 40%);">-FILES="General_Types.ttcn Osmocom_Types.ttcn GSM_Types.ttcn Osmocom_VTY_Functions.ttcn Native_Functions.ttcn Native_FunctionDefs.cc IPA_Types.ttcn IPA_CodecPort.ttcn IPA_CodecPort_CtrlFunct.ttcn IPA_CodecPort_CtrlFunctDef.cc IPA_Emulation.ttcnpp L3_Templates.ttcn BSSMAP_Templates.ttcn BSSMAP_Emulation.ttcn RLCMAC_CSN1_Types.ttcn GSM_RR_Types.ttcn RSL_Types.ttcn RSL_Emulation.ttcn MGCP_Emulation.ttcn MGCP_Types.ttcn MGCP_Templates.ttcn MGCP_CodecPort.ttcn MGCP_CodecPort_CtrlFunct.ttcn MGCP_CodecPort_CtrlFunctDef.cc BSSAP_CodecPort.ttcn BSSAP_Adapter.ttcn Osmocom_CTRL_Types.ttcn Osmocom_CTRL_Functions.ttcn Osmocom_CTRL_Adapter.ttcn RTP_CodecPort.ttcn RTP_CodecPort_CtrlFunct.ttcn RTP_CodecPort_CtrlFunctDef.cc RTP_Emulation.ttcn IuUP_Types.ttcn IuUP_EncDec.cc IuUP_Emulation.ttcn SCCP_Templates.ttcn"</span><br><span style="color: hsl(120, 100%, 40%);">+FILES="General_Types.ttcn Osmocom_Types.ttcn GSM_Types.ttcn Osmocom_VTY_Functions.ttcn Native_Functions.ttcn Native_FunctionDefs.cc IPA_Types.ttcn IPA_CodecPort.ttcn IPA_CodecPort_CtrlFunct.ttcn IPA_CodecPort_CtrlFunctDef.cc IPA_Emulation.ttcnpp L3_Templates.ttcn BSSMAP_Templates.ttcn BSSMAP_Emulation.ttcn RLCMAC_CSN1_Types.ttcn GSM_RR_Types.ttcn RSL_Types.ttcn RSL_Emulation.ttcn MGCP_Emulation.ttcn MGCP_Types.ttcn MGCP_Templates.ttcn MGCP_CodecPort.ttcn MGCP_CodecPort_CtrlFunct.ttcn MGCP_CodecPort_CtrlFunctDef.cc BSSAP_CodecPort.ttcn BSSAP_Adapter.ttcn Osmocom_CTRL_Types.ttcn Osmocom_CTRL_Functions.ttcn Osmocom_CTRL_Adapter.ttcn RTP_CodecPort.ttcn RTP_CodecPort_CtrlFunct.ttcn RTP_CodecPort_CtrlFunctDef.cc RTP_Emulation.ttcn IuUP_Types.ttcn IuUP_EncDec.cc IuUP_Emulation.ttcn SCCP_Templates.ttcn IPA_Testing.ttcn"</span><br><span> gen_links $DIR $FILES</span><br><span> </span><br><span> ignore_pp_results</span><br><span>diff --git a/library/IPA_Testing.ttcn b/library/IPA_Testing.ttcn</span><br><span>new file mode 100644</span><br><span>index 0000000..62aa143</span><br><span>--- /dev/null</span><br><span>+++ b/library/IPA_Testing.ttcn</span><br><span>@@ -0,0 +1,170 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* (C) 2018 by sysmocom s.f.m.c. GmbH <info@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * Author: Stefan Sperling <ssperling@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Released under the terms of GNU General Public License, Version 2 or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This module provides functions which implement IPA protocol tests.</span><br><span style="color: hsl(120, 100%, 40%);">+ * There are no test cases defined here. Instead, there are test functions which</span><br><span style="color: hsl(120, 100%, 40%);">+ * can be called by test cases in our test suites. Each such function will create</span><br><span style="color: hsl(120, 100%, 40%);">+ * an IPA_CT component and execute a test on this component, and expects destination</span><br><span style="color: hsl(120, 100%, 40%);">+ * IP address, TCP port, and connection mode parameters. Depending on the connection</span><br><span style="color: hsl(120, 100%, 40%);">+ * mode, a test function will either connect to an IPA server on the specified</span><br><span style="color: hsl(120, 100%, 40%);">+ * address and port, or listen for an IPA client on the specified address and port.</span><br><span style="color: hsl(120, 100%, 40%);">+ * This allows IPA tests to be run against any IPA speakers used by various test suites.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+module IPA_Testing {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import from IPL4asp_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from IPL4asp_PortType all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from IPA_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from Osmocom_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+type enumerated IPA_ConnectionMode {</span><br><span style="color: hsl(120, 100%, 40%);">+ CONNECT_TO_SERVER,</span><br><span style="color: hsl(120, 100%, 40%);">+ LISTEN_FOR_CLIENT</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Encoded IPA messages (network byte order) */</span><br><span style="color: hsl(120, 100%, 40%);">+const octetstring ipa_msg_ping := '0001FE00'O;</span><br><span style="color: hsl(120, 100%, 40%);">+const octetstring ipa_msg_pong := '0001FE01'O;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* A component which represents the system on which the IPA speaker is running. */</span><br><span style="color: hsl(120, 100%, 40%);">+type component system_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ port IPL4asp_PT IPL4;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Main component provided by this module. */</span><br><span style="color: hsl(120, 100%, 40%);">+type component IPA_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ port IPL4asp_PT IPL4;</span><br><span style="color: hsl(120, 100%, 40%);">+ timer g_Tguard;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* This guard timer prevents us from waiting too long if the IPA TCP connection hangs. */</span><br><span style="color: hsl(120, 100%, 40%);">+private altstep as_Tguard() runs on IPA_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ [] g_Tguard.timeout {</span><br><span style="color: hsl(120, 100%, 40%);">+ setverdict(fail, "Tguard timeout");</span><br><span style="color: hsl(120, 100%, 40%);">+ mtc.stop;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Send an encoded IPA message across an IPA TCP connection. */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_send_ipa_data(charstring ipa_ip, integer ipa_tcp_port, ConnectionId connId,</span><br><span style="color: hsl(120, 100%, 40%);">+ octetstring data) runs on IPA_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ var IPL4asp_Types.Result res;</span><br><span style="color: hsl(120, 100%, 40%);">+ var ASP_SendTo asp := {</span><br><span style="color: hsl(120, 100%, 40%);">+ connId := connId,</span><br><span style="color: hsl(120, 100%, 40%);">+ remName := ipa_ip,</span><br><span style="color: hsl(120, 100%, 40%);">+ remPort := ipa_tcp_port,</span><br><span style="color: hsl(120, 100%, 40%);">+ proto := {tcp := {}},</span><br><span style="color: hsl(120, 100%, 40%);">+ msg := data</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+ IPL4.send(asp);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Match an incoming IPA message. */</span><br><span style="color: hsl(120, 100%, 40%);">+private template ASP_RecvFrom t_recvfrom(template octetstring msg) := {</span><br><span style="color: hsl(120, 100%, 40%);">+ connId := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ remName := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ remPort := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ locName := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ locPort := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ proto := {tcp := {}},</span><br><span style="color: hsl(120, 100%, 40%);">+ userData := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ msg := msg</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Perform set up steps for a test function. */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_init(charstring ipa_ip, integer ipa_tcp_port,</span><br><span style="color: hsl(120, 100%, 40%);">+ IPA_ConnectionMode conmode) runs on IPA_CT return ConnectionId {</span><br><span style="color: hsl(120, 100%, 40%);">+ var IPL4asp_Types.Result res;</span><br><span style="color: hsl(120, 100%, 40%);">+ var ConnectionId connId;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ map(self:IPL4, system:IPL4);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (conmode == CONNECT_TO_SERVER) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Create an IPA connection over TCP. */</span><br><span style="color: hsl(120, 100%, 40%);">+ res := IPL4asp_PortType.f_IPL4_connect(IPL4, ipa_ip, ipa_tcp_port, "", -1, 0, {tcp := {}});</span><br><span style="color: hsl(120, 100%, 40%);">+ if (not ispresent(res.connId)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ setverdict(fail, "Could not connect IPA socket to ", ipa_ip, " port ",</span><br><span style="color: hsl(120, 100%, 40%);">+ ipa_tcp_port, "; check your configuration");</span><br><span style="color: hsl(120, 100%, 40%);">+ mtc.stop;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Listen for an incoming IPA connection on TCP. */</span><br><span style="color: hsl(120, 100%, 40%);">+ res := IPL4asp_PortType.f_IPL4_listen(IPL4, ipa_ip, ipa_tcp_port, {tcp := {}});</span><br><span style="color: hsl(120, 100%, 40%);">+ if (not ispresent(res.connId)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ setverdict(fail, "Could not listen on address ", ipa_ip, " port ",</span><br><span style="color: hsl(120, 100%, 40%);">+ ipa_tcp_port, "; check your configuration");</span><br><span style="color: hsl(120, 100%, 40%);">+ mtc.stop;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Activate guard timer. When changing the timeout value, keep in mind</span><br><span style="color: hsl(120, 100%, 40%);">+ * that test functions below may wait for some amount of time, which</span><br><span style="color: hsl(120, 100%, 40%);">+ * this guard timer should always exceed to avoid spurious failures.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ g_Tguard.start(60.0);</span><br><span style="color: hsl(120, 100%, 40%);">+ activate(as_Tguard());</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return res.connId;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Individual test case implementations.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_send_chopped_ipa_msg(charstring ipa_ip, integer ipa_tcp_port, ConnectionId connId,</span><br><span style="color: hsl(120, 100%, 40%);">+ octetstring msg) runs on IPA_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ const float delay := 6.0;</span><br><span style="color: hsl(120, 100%, 40%);">+ for (var integer i := 0; i < lengthof(msg); i := i + 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ log("sending byte ", msg[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+ f_send_ipa_data(ipa_ip, ipa_tcp_port, connId, msg[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+ f_sleep(delay);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Send a ping message one byte at a time, waiting for TCP buffer to flush between each byte. */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_TC_chopped_ipa_ping(charstring ipa_ip, integer ipa_tcp_port,</span><br><span style="color: hsl(120, 100%, 40%);">+ IPA_ConnectionMode conmode) runs on IPA_CT system system_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ var ConnectionId connId;</span><br><span style="color: hsl(120, 100%, 40%);">+ var ASP_RecvFrom asp_rx;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ connId := f_init(ipa_ip, ipa_tcp_port, conmode);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (conmode == CONNECT_TO_SERVER) {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_send_chopped_ipa_msg(ipa_ip, ipa_tcp_port, connId, ipa_msg_ping);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ IPL4.receive(t_recvfrom(omit)) -> value asp_rx {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_send_chopped_ipa_msg(asp_rx.remName, asp_rx.remPort, connId, ipa_msg_ping);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Expect a pong response. */</span><br><span style="color: hsl(120, 100%, 40%);">+ alt {</span><br><span style="color: hsl(120, 100%, 40%);">+ [] IPL4.receive(t_recvfrom(ipa_msg_pong)) -> value asp_rx {</span><br><span style="color: hsl(120, 100%, 40%);">+ log("received pong from ", asp_rx.remName, " port ", asp_rx.remPort, ": ", asp_rx.msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ setverdict(pass);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ [] IPL4.receive {</span><br><span style="color: hsl(120, 100%, 40%);">+ repeat;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Public functions.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Test suites may call these functions to create an IPA_CT component and run a test to completion.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+function f_run_TC_chopped_ipa_ping(charstring ipa_ip, integer ipa_tcp_port, IPA_ConnectionMode conmode) {</span><br><span style="color: hsl(120, 100%, 40%);">+ var IPA_Testing.IPA_CT vc_IPA_Testing := IPA_Testing.IPA_CT.create;</span><br><span style="color: hsl(120, 100%, 40%);">+ vc_IPA_Testing.start(IPA_Testing.f_TC_chopped_ipa_ping(ipa_ip, ipa_tcp_port, conmode));</span><br><span style="color: hsl(120, 100%, 40%);">+ vc_IPA_Testing.done;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/11241">change 11241</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/11241"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: osmo-ttcn3-hacks </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I246a405414e36a44dc1e308692faab8bf04da0e6 </div>
<div style="display:none"> Gerrit-Change-Number: 11241 </div>
<div style="display:none"> Gerrit-PatchSet: 5 </div>
<div style="display:none"> Gerrit-Owner: Stefan Sperling <ssperling@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>
<div style="display:none"> Gerrit-Reviewer: Stefan Sperling <ssperling@sysmocom.de> </div>