BTS_Test_ASCI: Add first ASCI test to check NCH support

Send Notification command to start and stop notifying an ASCI call.
When it starts, it is expected that NCH is received. Also it is expected
that NCH is received again. When it stops, it is expected that NCH is
not received anymore.

Change-Id: I3727c471663b731117a264f60d2f1ba5fd16928e
Related: OS#4851
diff --git a/bts/BTS_Tests.cfg b/bts/BTS_Tests.cfg
index c6f50ad..fb78eba 100644
--- a/bts/BTS_Tests.cfg
+++ b/bts/BTS_Tests.cfg
@@ -41,3 +41,4 @@
 BTS_Tests_SMSCB.control
 BTS_Tests_LAPDm.control
 BTS_Tests_VAMOS.control
+BTS_Tests_ASCI.control
diff --git a/bts/BTS_Tests.ttcn b/bts/BTS_Tests.ttcn
index 37d15b8..d893601 100644
--- a/bts/BTS_Tests.ttcn
+++ b/bts/BTS_Tests.ttcn
@@ -74,6 +74,7 @@
 import from TELNETasp_PortType all;
 import from BTS_Tests_LAPDm all;
 
+friend module BTS_Tests_ASCI;
 friend module BTS_Tests_SMSCB;
 friend module BTS_Tests_VAMOS;
 friend module BTS_Tests_virtphy;
diff --git a/bts/BTS_Tests_ASCI.ttcn b/bts/BTS_Tests_ASCI.ttcn
new file mode 100644
index 0000000..dfab7f6
--- /dev/null
+++ b/bts/BTS_Tests_ASCI.ttcn
@@ -0,0 +1,135 @@
+module BTS_Tests_ASCI {
+
+/* ASCI Integration Tests for OsmoBTS
+ *
+ * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: AGPL-3.0+
+ *
+ * Authors: Harald Welte; Andreas Eversberg
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import from Misc_Helpers all;
+import from General_Types all;
+import from Osmocom_Types all;
+import from GSM_Types all;
+import from L1CTL_PortType all;
+import from L1CTL_Types all;
+import from LAPDm_Types all;
+import from IPA_Emulation all;
+import from GSM_RR_Types all;
+import from L3_Templates all;
+
+import from MobileL3_CommonIE_Types all;
+
+import from RSL_Emulation all;
+import from RSL_Types all;
+
+import from BTS_Tests all;
+
+
+
+/* convert from boolean value to BIT1 */
+private function bool2bit1(boolean inp) return BIT1 {
+	if (inp) {
+		return '1'B;
+	} else {
+		return '0'B;
+	}
+}
+
+/* encode a VBS/VGCS call reference into it's OCT5 representation */
+private function f_enc_gcr(integer call_ref, boolean is_group_call, boolean ack_required := false)
+return OCT5
+{
+	var DescriptiveGroupOrBroadcastCallReference_V v := {
+		binaryCodingOfGroupOrBroadcastCallReference := int2bit(call_ref, 27),
+		sF := bool2bit1(is_group_call),
+		aF := bool2bit1(ack_required),
+		callPriority := '000'B,
+		cipheringInformation := '0000'B,
+		spare := '0000'B
+	}
+	return bit2oct(encvalue(v));
+}
+
+/* Send Notification command to start and stop notifying an ASCI call.
+ * When it starts, it is expected that NCH is received by MS. Also it is expected that NCH is received again.
+ * When it stops, it is expected that NCH is not received anymore. */
+testcase TC_vbs_notification() runs on test_CT
+{
+	timer T;
+
+	f_init();
+	f_init_l1ctl();
+	f_l1_tune(L1CTL);
+
+	var OCT5 gcr := f_enc_gcr(hex2int('2342'H), false, false);
+	var OCT3 chan_desc := '234266'O;
+	var octetstring notif_nch := '090620B42230000091A1330B2B2B2B2B2B2B2B2B2B2B2B'O;
+	var integer recv_count := 0;
+
+	log("Sending RSL NOTIF_CMD (start)");
+	RSL_CCHAN.send(ts_ASP_RSL_UD(ts_RSL_NOTIF_CMD_START(gcr, chan_desc)));
+
+	/* NCH must be received twice. */
+	T.start(2.0);
+	alt {
+	[] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0), ?, notif_nch)) {
+		log("Received matching NOTIFICATION/NCH.");
+		recv_count := recv_count + 1;
+		if (recv_count != 2) {
+			repeat;
+		}
+		T.stop;
+		}
+	[] L1CTL.receive { repeat; }
+	[] T.timeout {
+		setverdict(fail, "Timeout waiting for NCH message");
+		}
+	}
+
+	log("Sending RSL NOTIF_CMD (stop)");
+	RSL_CCHAN.send(ts_ASP_RSL_UD(ts_RSL_NOTIF_CMD_STOP(gcr)));
+
+	/* Flush pending messages and be sure that the sending of notifications has stopped. */
+	f_sleep(1.0);
+	L1CTL.clear;
+
+	/* NCH must not be received. */
+	T.start(2.0);
+	alt {
+	[] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0), ?, notif_nch)) {
+		T.stop;
+		setverdict(fail, "Received unexpected NOTIFICATION/NCH.");
+		}
+	[] L1CTL.receive { repeat; }
+	[] T.timeout {
+		log("Not received NOTIFICATION/NCH. (as expected)");
+		setverdict(pass);
+		}
+	}
+
+	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
+}
+
+control {
+	execute( TC_vbs_notification() );
+
+}
+
+}