module BSC_Tests_CBSP {

/* CBSP Integration Tests for OsmoBSC
 * (C) 2019 by Harald Welte <laforge@gnumonks.org>
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 *
 * This test suite tests OsmoBSC while emulating the CBC (Cell Broadcast Centre)
 */

import from General_Types all;
import from Osmocom_Types all;
import from GSM_Types all;
import from IPL4asp_Types all;
import from BSSAP_Types all;
import from BSSMAP_Templates all;

import from BSC_Tests all;

import from IPA_Emulation all;
import from IPA_CodecPort all;
import from IPA_Types all;

import from MobileL3_Types all;
import from MobileL3_RRM_Types all;
import from L3_Templates all;

import from RSL_Types all;
import from RSL_Emulation all;

import from CBSP_Types all;
import from CBSP_Templates all;
import from CBSP_Adapter all;
import from CBSP_CodecPort all;

modulepar {
	charstring mp_cbc_ip := "0.0.0.0";
	integer mp_cbc_port := 48049;
	integer mp_bsc_cbsp_port := 48050;

	/* BTS 0: 001-01-1-0 with CBCH
	 * BTS 1: 001-01-1-1 with CBCH
	 * BTS 2: 001-01-2-1 with CBCH
	 * BTS 3: 001-01-2-3 without CBCH */
	GsmCgiAbstract mp_cgi_bts0 := { '001'H, '01'H, 1, 0 };
	GsmCgiAbstract mp_cgi_bts1 := { '001'H, '01'H, 1, 1 };
	GsmCgiAbstract mp_cgi_bts2 := { '001'H, '01'H, 2, 1 };
	GsmCgiAbstract mp_cgi_bts3 := { '001'H, '01'H, 2, 3 };
}

private type record GsmCgiAbstract {
	GsmMcc mcc,
	GsmMnc mnc,
	GsmLac lac,
	GsmCellId ci
};
private template (value) BSSMAP_FIELD_CellIdentification_CGI bssmap_cgi(GsmCgiAbstract cgi) :=
	ts_BSSMAP_CI_CGI(cgi.mcc, cgi.mnc, cgi.lac, cgi.ci);
private template (value) BSSMAP_FIELD_CellIdentification_LAC_CI bssmap_lac_ci(GsmCgiAbstract cgi) :=
	ts_BSSMAP_CI_LAC_CI(cgi.lac, cgi.ci);
private template (value) BSSMAP_FIELD_CellIdentification_LAI bssmap_lai(GsmCgiAbstract cgi) :=
	ts_BSSMAP_CI_LAI(cgi.mcc, cgi.mnc, cgi.lac);
private template (value) OCT2 bssmap_lac(GsmCgiAbstract cgi) := ts_BSSMAP_CI_LAC(cgi.lac);
private template (value) OCT2 bssmap_ci(GsmCgiAbstract cgi) := ts_BSSMAP_CI_CI(cgi.ci);

type component cbsp_test_CT extends test_CT, CBSP_Adapter_CT {
	var uint16_t g_cbsp_msg_id := 0;
	var uint16_t g_cbsp_ser_no := 0;
}

private function f_g_cbsp_next_msg_id_ser_no() runs on cbsp_test_CT
{
	g_cbsp_msg_id := g_cbsp_msg_id + 1;
	g_cbsp_ser_no := g_cbsp_ser_no + 1;
	log("g_cbsp_msg_id=", g_cbsp_msg_id, "  g_cbsp_ser_no=", g_cbsp_ser_no);
}

private altstep as_IgnRSL(template RSL_Message tr) runs on cbsp_test_CT {
[] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr)) { repeat; }
[] IPA_RSL[1].receive(tr_ASP_RSL_UD(tr)) { repeat; }
[] IPA_RSL[2].receive(tr_ASP_RSL_UD(tr)) { repeat; }
}

private altstep as_FailRSL() runs on cbsp_test_CT {
var template RSL_Message tr := (tr_RSL_SMSCB_CMD);
var ASP_RSL_Unitdata rx;
[] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr)) -> value rx {
	setverdict(fail, "Received unexpected RSL ", rx);
	mtc.stop;
	}
[] IPA_RSL[1].receive(tr_ASP_RSL_UD(tr)) -> value rx {
	setverdict(fail, "Received unexpected RSL ", rx);
	mtc.stop;
	}
[] IPA_RSL[2].receive(tr_ASP_RSL_UD(tr)) -> value rx {
	setverdict(fail, "Received unexpected RSL ", rx);
	mtc.stop;
	}
}

private function f_init(float guard_timeout := 30.0) runs on cbsp_test_CT {
	BSC_Tests.f_init(guard_timeout := guard_timeout);
	activate(as_IgnRSL((tr_RSL_BCCH_INFO, tr_RSL_SACCH_FILL,
			    tr_RSL_NO_BCCH_INFO, tr_RSL_NO_SACCH_FILL,
			    tr_RSL_MsgTypeD(?))));
	activate(as_FailRSL());
}
private function f_cbsp_init_client() runs on cbsp_test_CT {
	f_init();
	CBSP_Adapter.f_connect(mp_bsc_ip, mp_bsc_cbsp_port, "", -1);
	/* FIXME: osmo-bsc should probably still send a CBSP RESTART, but to get the current tests running, let's first
	 * ignore this aspect */
	setverdict(pass);
}

private function f_cbsp_init_server(uint16_t cbsp_msg_id, uint16_t cbsp_ser_no, float guard_timeout := 30.0) runs on cbsp_test_CT {
	var ASP_Event asp_evt;
	timer T := 10.0;

	f_init(guard_timeout := guard_timeout);
	CBSP_Adapter.f_bind(mp_cbc_ip, mp_cbc_port);

	T.start;
	alt {
	[] CBSP[0].receive(ASP_Event:{connOpened:=?}) -> value asp_evt {
		g_cbsp_conn_id[0] := asp_evt.connOpened.connId;
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for incoming connection to CBSP Port");
		mtc.stop;
		}
	}
	f_expect_cbsp_restart();

	g_cbsp_msg_id := cbsp_msg_id;
	g_cbsp_ser_no := cbsp_ser_no;
	log("g_cbsp_msg_id=", g_cbsp_msg_id, "  g_cbsp_ser_no=", g_cbsp_ser_no);

	f_cbsp_reset_bss(0);
}
private function f_expect_cbsp_restart() runs on cbsp_test_CT {
	interleave {
	[] CBSP[0].receive(tr_CBSP_Recv(?, tr_CBSP_RESTART(?, CBSP_BC_MSGT_CBS, CBSP_RI_DATA_LOST)));
	/* should we also expect a restart for emergency related messages? */
	//[] CBSP[0].receive(tr_CBSP_Recv(?, tr_CBSP_RESTART(?, CBSP_BC_MSGT_EMERG, CBSP_RI_DATA_LOST)));
	}
}

/* Generate a CBSP payload: random size for payload_len == 0, or specific fixed size for payload_len > 0. */
function f_gen_page(integer payload_len := 0) return CBSP_IE {
	if (payload_len < 1) {
		/* The maximum CBSP page payload space is 88, but 6 bytes of payload header are added in the first page:
		 * the maximum length generated here thus is 82. The minimum generated length is 1 (avoiding zero
		 * length). Note, f_rnd_int(82) returns [0..81], so this results in a len ranging [1..82]: */
		payload_len := 1 + f_rnd_int(82);
	}
	log("Generating CBSP payload: ", payload_len, " octets");
	var octetstring payload := f_rnd_octstring(payload_len);
	return valueof(ts_CbspMsgContent(payload, payload_len));
}

function f_cbsp_reset_bss(integer idx) runs on cbsp_test_CT {
	/* Make sure no CBSP ETWS commands from a previous CBSP test remain in the RSL queue */
	IPA_RSL[0].clear;
	IPA_RSL[1].clear;
	IPA_RSL[2].clear;

	var template (value) CBSP_PDU tx;
	timer T := 3.0;
	tx := ts_CBSP_RESET(cell_list := ts_BSSMAP_CIL_BSS);
	CBSP[idx].clear;
	CBSP[idx].send(ts_CBSP_Send(g_cbsp_conn_id[idx], tx));
	T.start;
	alt {
	[] CBSP[idx].receive(tr_CBSP_Recv(?, tr_CBSP_RESET_COMPL(cell_list := ts_BSSMAP_CIL_BSS)));
	[] CBSP[idx].receive {
		setverdict(fail, "received unexpected CBSP");
		mtc.stop;
		}
	[] T.timeout {
		setverdict(fail, "timeout waiting for RESET COMPLETE");
		mtc.stop;
		}
	}
}

/* send a WRITE CBS to the BSC; expect either COMPLETE or FAILURE in response*/
function f_cbsp_write_emerg(uint16_t msg_id, uint16_t ser_no,
			template (value) BSSMAP_FIELD_CellIdentificationList cell_list := ts_BSSMAP_CIL_BSS,
			template (value) uint8_t emerg_ind := 1,
			template (value) uint16_t warn_type := oct2int('0780'O),
			template (value) uint16_t warn_per := 5,
			template BSSMAP_FIELD_CellIdentificationList success_list := ?,
			template CBSP_FailureListItems fail_list := omit) runs on cbsp_test_CT {
	var template (value) CBSP_PDU tx;
	var template CBSP_PDU rx;
	var CBSP_IEs pages := {f_gen_page()};

	tx := ts_CBSP_WRITE_EMERG(msg_id, ser_no, cell_list, emerg_ind, warn_type, warn_per);
	CBSP[0].send(ts_CBSP_Send(g_cbsp_conn_id[0], tx));
	if (istemplatekind(fail_list, "omit")) {
		rx := tr_CBSP_WRITE_CBS_COMPL(msg_id, ser_no, success_list, omit);
	} else {
		rx := tr_CBSP_WRITE_CBS_FAIL(msg_id, ser_no, fail_list, *, success_list, omit);
	}
	alt {
	[] CBSP[0].receive(tr_CBSP_Recv(g_cbsp_conn_id[0], rx)) {
		setverdict(pass);
		}
	[] CBSP[0].receive(tr_CBSP_Recv(g_cbsp_conn_id[0], ?)) {
		setverdict(fail, "Received unexpected CBSP");
		mtc.stop;
		}
	}
}

/* send a WRITE CBS to the BSC; expect either COMPLETE or FAILURE in response*/
function f_cbsp_write(uint16_t msg_id, uint16_t ser_no,
		      template (value) BSSMAP_FIELD_CellIdentificationList cell_list := ts_BSSMAP_CIL_BSS,
		      template (value) CBSP_Category category := CBSP_CATEG_NORMAL,
		      uint16_t rep_period := 10, uint16_t num_bcast_req := 1,
		      uint8_t dcs := 0, uint8_t channel_ind := 0, CBSP_IEs content,
		      template BSSMAP_FIELD_CellIdentificationList success_list := ?,
		      template CBSP_FailureListItems fail_list := omit) runs on cbsp_test_CT {
	var template (value) CBSP_PDU tx;
	var template CBSP_PDU rx;

	tx := ts_CBSP_WRITE_CBS(msg_id, ser_no, cell_list, channel_ind, category,
				rep_period, num_bcast_req, dcs, content);
	CBSP[0].send(ts_CBSP_Send(g_cbsp_conn_id[0], tx));
	if (istemplatekind(fail_list, "omit")) {
		rx := tr_CBSP_WRITE_CBS_COMPL(msg_id, ser_no, success_list, channel_ind);
	} else {
		rx := tr_CBSP_WRITE_CBS_FAIL(msg_id, ser_no, fail_list, *, success_list, channel_ind);
	}
	alt {
	[] CBSP[0].receive(tr_CBSP_Recv(g_cbsp_conn_id[0], rx)) {
		setverdict(pass);
		}
	[] CBSP[0].receive(tr_CBSP_Recv(g_cbsp_conn_id[0], ?)) {
		setverdict(fail, "Received unexpected CBSP");
		mtc.stop;
		}
	}
}

/* send a REPLACE CBS to the BSC; expect either COMPLETE or FAILURE in response*/
function f_cbsp_replace(uint16_t msg_id, uint16_t new_ser_no, uint16_t old_ser_no,
		      template (value) BSSMAP_FIELD_CellIdentificationList cell_list := ts_BSSMAP_CIL_BSS,
		      template (value) CBSP_Category category := CBSP_CATEG_NORMAL,
		      uint16_t rep_period := 10, uint16_t num_bcast_req := 1,
		      uint8_t dcs := 0, uint8_t channel_ind := 0, CBSP_IEs content,
		      template BSSMAP_FIELD_CellIdentificationList success_list := ?,
		      template CBSP_FailureListItems fail_list := omit) runs on cbsp_test_CT {
	var template (value) CBSP_PDU tx;
	var template CBSP_PDU rx;

	tx := ts_CBSP_REPLACE_CBS(msg_id, new_ser_no, old_ser_no, cell_list, channel_ind, category,
				rep_period, num_bcast_req, dcs, content);
	CBSP[0].send(ts_CBSP_Send(g_cbsp_conn_id[0], tx));
	if (istemplatekind(fail_list, "omit")) {
		rx := tr_CBSP_REPLACE_CBS_COMPL(msg_id, new_ser_no, old_ser_no, ?, success_list,
						channel_ind);
	} else {
		rx := tr_CBSP_REPLACE_CBS_FAIL(msg_id, new_ser_no, old_ser_no, fail_list, *, success_list,
					       channel_ind);
	}
	alt {
	[] CBSP[0].receive(tr_CBSP_Recv(g_cbsp_conn_id[0], rx)) {
		setverdict(pass);
		}
	[] CBSP[0].receive(tr_CBSP_Recv(g_cbsp_conn_id[0], ?)) {
		setverdict(fail, "Received unexpected CBSP");
		mtc.stop;
		}
	}
}
/* send a KILL CBS to the BSC; expect either COMPLETE or FAILURE in response*/
function f_cbsp_kill(uint16_t msg_id, uint16_t ser_no, template (omit) uint8_t channel_ind := 0,
		     template (value) BSSMAP_FIELD_CellIdentificationList cell_list := ts_BSSMAP_CIL_BSS,
		     template BSSMAP_FIELD_CellIdentificationList success_list := ?,
		     template CBSP_FailureListItems fail_list := omit) runs on cbsp_test_CT
{
	var template (value) CBSP_PDU tx;
	var template CBSP_PDU rx;

	tx := ts_CBSP_KILL(msg_id, ser_no, cell_list, channel_ind);
	CBSP[0].send(ts_CBSP_Send(g_cbsp_conn_id[0], tx));
	if (istemplatekind(fail_list, "omit")) {
		rx := tr_CBSP_KILL_COMPL(msg_id, ser_no, compl_list:=*, cell_list:=success_list,
					 channel_ind:=channel_ind);
	} else {
		rx := tr_CBSP_KILL_FAIL(msg_id, ser_no, fail_list, compl_list:=*, cell_list:=success_list,
					channel_ind:=channel_ind);
	}
	alt {
	[] CBSP[0].receive(tr_CBSP_Recv(g_cbsp_conn_id[0], rx)) {
		setverdict(pass);
		}
	[] CBSP[0].receive(tr_CBSP_Recv(g_cbsp_conn_id[0], ?)) {
		setverdict(fail, "Received unexpected CBSP");
		mtc.stop;
		}
	}
}

template (present) RSL_IE_CbCommandType
tr_RslCbCmdType(template (present) uint2_t lblock := ?, template (present) RSL_CbCommand cmd := ?) := {
	command := cmd,
	default_bcast_null := ?,
	spare := ?,
	last_block := lblock
}

/* translate blocks count to RSL_CB_CMD_LASTBLOCK_1..4 values */
private function f_cbsp_block_count_enc(integer num_blocks) return integer
{
	if (num_blocks < 1 or num_blocks > 4) {
		setverdict(fail, "Invalid num_blocks: ", num_blocks);
		mtc.stop;
	}
	if (num_blocks == 4) {
		return 0;
	}
	return num_blocks;
}

/* build a RSL_Message receive template from a CBSP page */
private function f_page2rsl(CBSP_IE page, uint16_t msg_id, uint16_t ser_no, boolean ext_cbch := false,
                            template (present) integer expect_blocks := ?)
return template (present) RSL_Message
{
	var template RSL_Message tr;
	var integer len;
	var integer num_blocks;
	var octetstring payload;

	payload := int2oct(ser_no, 2) & int2oct(msg_id, 2) & '0011'O & page.body.msg_content.val;
	len := lengthof(payload);
	num_blocks := len / 22;
	if (len mod 22 > 0) {
		num_blocks := num_blocks + 1;
	}

	if (not istemplatekind(expect_blocks, "omit") and not match(num_blocks, expect_blocks)) {
		setverdict(fail, "mismatch: CBSP page expect_blocks == ", expect_blocks, ", but generated num_blocks == ", num_blocks);
		mtc.stop;
	}

	var integer lblock := f_cbsp_block_count_enc(num_blocks);

	tr := tr_RSL_SMSCB_CMD(tr_RslCbCmdType(lblock), f_pad_oct(payload, 88, '00'O));
	if (ext_cbch) {
		tr.ies[3] := tr_RSL_IE(RSL_IE_Body:{smscb_chan_ind := 1});
		tr.ies[4] := *;
	}
	return tr;
}

/***********************************************************************
 * Test Cases
 ***********************************************************************/

/* Test if BSC (server) accepts connections from CBC (client) */
testcase TC_cbsp_bsc_server() runs on cbsp_test_CT {
	f_cbsp_init_client();
	setverdict(pass);
}

/* Test if BSC (client) is connecting to CBC (server) */
testcase TC_cbsp_bsc_client() runs on cbsp_test_CT {
	f_cbsp_init_server(0, 0);
	setverdict(pass);
}

/* Test if a BSS-global RESET is executed successfully */
testcase TC_cbsp_reset_bss() runs on cbsp_test_CT {
	f_cbsp_init_server(0, 0);

	f_cbsp_reset_bss(0);
	setverdict(pass);
}

testcase TC_cbsp_write() runs on cbsp_test_CT {
	var template (value) CBSP_PDU tx;
	var CBSP_IEs pages := {f_gen_page()};
	f_cbsp_init_server(0, 0);

	tx := ts_CBSP_WRITE_CBS(msg_id:=23,  new_ser_nr:=42, cell_list:=ts_BSSMAP_CIL_BSS,
				channel_ind:=0, category:=CBSP_CATEG_NORMAL,
				rep_period:=10, num_bcast_req:=1, dcs := 0,
				content:=pages);

	CBSP[0].send(ts_CBSP_Send(g_cbsp_conn_id[0], tx));
	f_sleep(10.0);
}

/* Write to entire BSS; three cells succeed; one fails (no CBCH) */
function f_tc_cbsp_write_bss(integer payload_len := -1, template (present) integer expect_blocks) runs on cbsp_test_CT {
	var CBSP_IEs pages := {f_gen_page(payload_len := payload_len)};
	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list;
	cell_list := ts_BSSMAP_CIL_BSS;
	f_cbsp_write(g_cbsp_msg_id, g_cbsp_ser_no, cell_list, content:=pages,
		     success_list:=tr_BSSMAP_CIL_CGI({?,?,?}), fail_list:={?});

	var template RSL_Message tr := f_page2rsl(pages[0], g_cbsp_msg_id, g_cbsp_ser_no, expect_blocks := expect_blocks);
	log("RSL[0,1,2] EXPECTING ", tr_ASP_RSL_UD(tr));
	interleave {
	[] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr)) { log("Got SMSCB CMD on RSL[0]"); }
	[] IPA_RSL[1].receive(tr_ASP_RSL_UD(tr)) { log("Got SMSCB CMD on RSL[1]"); }
	[] IPA_RSL[2].receive(tr_ASP_RSL_UD(tr)) { log("Got SMSCB CMD on RSL[2]"); }
	}
	setverdict(pass);

	/* Make the next test run (if any) use different msg_id and ser_no */
	f_g_cbsp_next_msg_id_ser_no();
}
testcase TC_cbsp_write_bss() runs on cbsp_test_CT {
	f_cbsp_init_server(1001, 1501, guard_timeout := 60.0);
	/* In the SMSCB message, there is a head followed by payload,
	 * and the resulting data is segmented in blocks of 22 octets (<= 4 blocks).
	 *
	 * [head][...payload....]|[....................]|[....................]|[....................]
	 *       0               |16                    |38                    |60                   |82
	 * 0    5                |22                    |44                    |66                   |88
	 *
	 *         blocks count:   1     | 2      | 3      | 4
	 * payload octets count:   1..16 | 17..38 | 39..60 | 61..82
	 */
	f_tc_cbsp_write_bss(payload_len := 1, expect_blocks := 1);
	f_tc_cbsp_write_bss(payload_len := 2, expect_blocks := 1);
	f_tc_cbsp_write_bss(payload_len := 16, expect_blocks := 1);
	f_tc_cbsp_write_bss(payload_len := 17, expect_blocks := 2);
	f_tc_cbsp_write_bss(payload_len := 23, expect_blocks := 2);
	f_tc_cbsp_write_bss(payload_len := 38, expect_blocks := 2);
	f_tc_cbsp_write_bss(payload_len := 39, expect_blocks := 3);
	f_tc_cbsp_write_bss(payload_len := 42, expect_blocks := 3);
	f_tc_cbsp_write_bss(payload_len := 60, expect_blocks := 3);
	f_tc_cbsp_write_bss(payload_len := 61, expect_blocks := 4);
	f_tc_cbsp_write_bss(payload_len := 77, expect_blocks := 4);
	f_tc_cbsp_write_bss(payload_len := 82, expect_blocks := 4);
}

/* Write to single BTS supporting CBCH: success */
testcase TC_cbsp_write_bts_cgi() runs on cbsp_test_CT {
	var CBSP_IEs pages := {f_gen_page()};
	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list;
	cell_list := ts_BSSMAP_CIL_CGI({bssmap_cgi(mp_cgi_bts0)});
	f_cbsp_init_server(2001, 2501);
	f_cbsp_write(g_cbsp_msg_id, g_cbsp_ser_no, cell_list, content:=pages,
		     success_list:=cell_list, fail_list:=omit);
	var template RSL_Message tr := f_page2rsl(pages[0], g_cbsp_msg_id, g_cbsp_ser_no);
	IPA_RSL[0].receive(tr_ASP_RSL_UD(tr));
	f_sleep(5.0);
}

/* Write to single BTS not supporting CBCH: failure */
testcase TC_cbsp_write_bts_no_cbch() runs on cbsp_test_CT {
	var CBSP_IEs pages := {f_gen_page()};
	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list;
	cell_list := ts_BSSMAP_CIL_CGI({bssmap_cgi(mp_cgi_bts3)});
	f_cbsp_init_server(3001, 3501);
	f_cbsp_write(g_cbsp_msg_id, g_cbsp_ser_no, cell_list, content:=pages,
		     success_list:=omit, fail_list:={?});
	f_sleep(5.0);
}

/* Write to single non-existant BTS */
testcase TC_cbsp_write_unknown_bts() runs on cbsp_test_CT {
	var CBSP_IEs pages := {f_gen_page()};
	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list;
	cell_list := ts_BSSMAP_CIL_CGI({ts_BSSMAP_CI_CGI(mp_cgi_bts0.mcc, mp_cgi_bts1.mnc, 22222, 33333)});
	f_cbsp_init_server(4001, 4501);
	f_cbsp_write(g_cbsp_msg_id, g_cbsp_ser_no, cell_list, content:=pages,
		     success_list:=omit, fail_list:={?});
	f_sleep(5.0);
}

/* Write to single BTS using LAC+CI */
testcase TC_cbsp_write_lac_ci() runs on cbsp_test_CT {
	var CBSP_IEs pages := {f_gen_page()};
	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list;
	cell_list := ts_BSSMAP_CIL_LAC_CI({bssmap_lac_ci(mp_cgi_bts0)});
	f_cbsp_init_server(5001, 5501);
	f_cbsp_write(g_cbsp_msg_id, g_cbsp_ser_no, cell_list, content:=pages,
		     success_list:=?, fail_list:=omit);
	IPA_RSL[0].receive(tr_ASP_RSL_UD(f_page2rsl(pages[0], g_cbsp_msg_id, g_cbsp_ser_no)));
	f_sleep(5.0);
}

/* Write to single BTS using CI */
testcase TC_cbsp_write_ci() runs on cbsp_test_CT {
	var CBSP_IEs pages := {f_gen_page()};
	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list;
	cell_list := ts_BSSMAP_CIL_CI({bssmap_ci(mp_cgi_bts0)});
	f_cbsp_init_server(6001, 6501);
	f_cbsp_write(g_cbsp_msg_id, g_cbsp_ser_no, cell_list, content:=pages,
		     success_list:=?, fail_list:=omit);
	IPA_RSL[0].receive(tr_ASP_RSL_UD(f_page2rsl(pages[0], g_cbsp_msg_id, g_cbsp_ser_no)));
	f_sleep(5.0);
}

/* Write to single BTS using LAI */
testcase TC_cbsp_write_lai() runs on cbsp_test_CT {
	var CBSP_IEs pages := {f_gen_page()};
	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list;
	/* bts0 and bts1 have the same LAI (only differ in cell identity).
	 * bts2 and bts3 also have the same LAI, but only bts2 has a CBCH.
	 * Target only bts2.
	 */
	cell_list := ts_BSSMAP_CIL_LAI({bssmap_lai(mp_cgi_bts2)});
	f_cbsp_init_server(7001, 7501);
	f_cbsp_write(g_cbsp_msg_id, g_cbsp_ser_no, cell_list, content:=pages,
		     success_list:=?, fail_list:=omit);
	IPA_RSL[2].receive(tr_ASP_RSL_UD(f_page2rsl(pages[0], g_cbsp_msg_id, g_cbsp_ser_no)));
	f_sleep(5.0);
}

/* Write to two BTS using LAC */
testcase TC_cbsp_write_lac() runs on cbsp_test_CT {
	var CBSP_IEs pages := {f_gen_page()};
	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list;
	cell_list := ts_BSSMAP_CIL_LAC({bssmap_lac(mp_cgi_bts0)});
	f_cbsp_init_server(8001, 8501);
	f_cbsp_write(g_cbsp_msg_id, g_cbsp_ser_no, cell_list, content:=pages,
		     success_list:=?, fail_list:=omit);
	var template RSL_Message tr := f_page2rsl(pages[0], g_cbsp_msg_id, g_cbsp_ser_no);
	interleave {
	[] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr));
	[] IPA_RSL[1].receive(tr_ASP_RSL_UD(tr));
	}
	f_sleep(5.0);
}

/* Write a message, then replace it */
testcase TC_cbsp_write_then_replace() runs on cbsp_test_CT {
	var CBSP_IEs pages := {f_gen_page()};
	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list;
	cell_list := ts_BSSMAP_CIL_LAC_CI({bssmap_lac_ci(mp_cgi_bts0)});
	f_cbsp_init_server(9001, 9501);
	f_cbsp_write(g_cbsp_msg_id, g_cbsp_ser_no, cell_list, num_bcast_req:=10, content:=pages,
		     success_list:=?, fail_list:=omit);

	IPA_RSL[0].receive(tr_ASP_RSL_UD(f_page2rsl(pages[0], g_cbsp_msg_id, g_cbsp_ser_no)));

	/* Replace: keep the same msg_id, use a new ser_no */
	var uint16_t old_ser_no := g_cbsp_ser_no;
	g_cbsp_ser_no := g_cbsp_ser_no + 1;
	f_cbsp_replace(g_cbsp_msg_id, g_cbsp_ser_no, old_ser_no, cell_list, content:=pages,
		       success_list:=?, fail_list:=omit);

	IPA_RSL[0].receive(tr_ASP_RSL_UD(f_page2rsl(pages[0], g_cbsp_msg_id, g_cbsp_ser_no)));
	f_sleep(1.0);
	setverdict(pass);
}

/* Replace a message that doesn't exist: failure */
testcase TC_cbsp_replace_nonexist() runs on cbsp_test_CT {
	var CBSP_IEs pages := {f_gen_page()};
	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list;
	cell_list := ts_BSSMAP_CIL_LAC_CI({bssmap_lac_ci(mp_cgi_bts0)});
	f_cbsp_init_server(10001, 10501);
	f_cbsp_replace(10, 10023, 10042, cell_list, content:=pages,
		       success_list:=omit, fail_list:=?);
}

/* Write more messages than can be scheduled */
testcase TC_cbsp_write_too_many() runs on cbsp_test_CT {
	/* repeating three pages at an interval of 1 is impossible */
	var CBSP_IEs pages := {f_gen_page(), f_gen_page(), f_gen_page()};
	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list;
	cell_list := ts_BSSMAP_CIL_LAC_CI({bssmap_lac_ci(mp_cgi_bts0)});
	f_cbsp_init_server(11001, 11501);
	f_cbsp_write(g_cbsp_msg_id, g_cbsp_ser_no, cell_list, rep_period:=1, content:=pages,
		     success_list:=omit, fail_list:=?);
}

/* Kill message that doesn't exist: failure */
testcase TC_cbsp_kill_nonexist() runs on cbsp_test_CT {
	var CBSP_IEs pages := {f_gen_page()};
	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list;
	cell_list := ts_BSSMAP_CIL_LAC_CI({bssmap_lac_ci(mp_cgi_bts0)});
	f_cbsp_init_server(12001, 12501);
	f_cbsp_kill(g_cbsp_msg_id, g_cbsp_ser_no, 0, cell_list, success_list:=omit, fail_list:=?);
}
/* Write a message, then kill it */
testcase TC_cbsp_write_then_kill() runs on cbsp_test_CT {
	var CBSP_IEs pages := {f_gen_page()};
	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list;
	cell_list := ts_BSSMAP_CIL_LAC_CI({bssmap_lac_ci(mp_cgi_bts0)});
	f_cbsp_init_server(13001, 13501);
	f_cbsp_write(g_cbsp_msg_id, g_cbsp_ser_no, cell_list, content:=pages, success_list:=?, fail_list:=omit);
	f_cbsp_kill(g_cbsp_msg_id, g_cbsp_ser_no, 0, cell_list, success_list:=?, fail_list:=omit);
}

/* Write a message, then reset all messages */
testcase TC_cbsp_write_then_reset() runs on cbsp_test_CT {
	var CBSP_IEs pages := {f_gen_page()};
	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list;
	cell_list := ts_BSSMAP_CIL_LAC_CI({bssmap_lac_ci(mp_cgi_bts0)});
	f_cbsp_init_server(14001, 14501);
	f_cbsp_write(g_cbsp_msg_id, g_cbsp_ser_no, cell_list, content:=pages, success_list:=?, fail_list:=omit);
	f_cbsp_reset_bss(0);
}

private const octetstring c_ETWS_sec_default :=
	'00000000000000000000000000000000000000000000000000'O &
	'00000000000000000000000000000000000000000000000000'O;
function f_gen_etws_pn(uint16_t ser_nr, uint16_t msg_id, OCT2 msg_type := '0780'O,
			octetstring sec_inf := c_ETWS_sec_default) return octetstring {
	return int2oct(ser_nr, 2) & int2oct(msg_id, 2) & msg_type & sec_inf;
}

/* Write ETWS PN to single BTS; verify it arrives on DCHAN */
testcase TC_cbsp_emerg_write_bts_cgi_dchan() runs on cbsp_test_CT {
	var CBSP_IEs pages := {f_gen_page()};
	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list;
	var ASP_RSL_Unitdata rx_rsl_ud;

	cell_list := ts_BSSMAP_CIL_CGI({bssmap_cgi(mp_cgi_bts0)});
	f_cbsp_init_server(15001, 15501);

	/* first establish a dedicated channel */
	var DchanTuple dt := f_est_dchan('23'O, 23, '00010203040506'O);

	/* then send ETWS PN */
	f_cbsp_write_emerg(g_cbsp_msg_id, g_cbsp_ser_no, cell_list);
	var template (present) octetstring tr_apdu := f_gen_etws_pn(g_cbsp_msg_id, g_cbsp_ser_no);
	timer T := 5.0;
	T.start;
	alt {
	[] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_DATA_REQ(dt.rsl_chan_nr, ?, ?))) -> value rx_rsl_ud {
		var RSL_IE_Body l3_ie;
		if (f_rsl_find_ie(rx_rsl_ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
			setverdict(fail, "RSL DATA REQ without L3?");
			mtc.stop;
		}
		var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
		var template (present) APDU_Flags_V tr_flags := {
			lastSeg := '0'B,
			firstSeg := '0'B,
			cR := '0'B,
			spare := '0'B
		};
		if (match(l3, tr_RR_APP_INFO('0001'B, tr_apdu, tr_flags))) {
			setverdict(pass);
			}
		}
	[] IPA_RSL[0].receive { repeat; }
	[] T.timeout {
		setverdict(fail, "Waiting for APP INFO");
		}
	}
}

/* Write ETWS PN to single BTS; verify it arrives on CCHAN */
testcase TC_cbsp_emerg_write_bts_cgi_cchan() runs on cbsp_test_CT {
	var CBSP_IEs pages := {f_gen_page()};
	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list;
	var ASP_RSL_Unitdata rx_rsl_ud;

	cell_list := ts_BSSMAP_CIL_CGI({bssmap_cgi(mp_cgi_bts0)});
	f_cbsp_init_server(16001, 16501);

	f_cbsp_write_emerg(g_cbsp_msg_id, g_cbsp_ser_no, cell_list);
	var template (present) octetstring tr_apdu := f_gen_etws_pn(g_cbsp_ser_no, g_cbsp_msg_id);
	timer T := 5.0;
	T.start;
	alt {
	[] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_OSMO_ETWS_CMD(t_RslChanNr_PCH_AGCH(0), tr_apdu))) {
		setverdict(pass);
		}
	[] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_OSMO_ETWS_CMD(?,?))) {
		setverdict(fail, "Received unexpected OSMO_ETWS_CMD");
		mtc.stop;
		}
	[] IPA_RSL[0].receive { repeat; }
	[] T.timeout {
		setverdict(fail, "Timeout waiting for RSL_OSMO_ETWS_CMD");
		mtc.stop;
		}
	}
}

/* Write ETWS PN to single BTS; verify it arrives on CCHAN */
testcase TC_cbsp_emerg_write_bts_cgi_cchan_disable() runs on cbsp_test_CT {
	var CBSP_IEs pages := {f_gen_page()};
	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list;
	var ASP_RSL_Unitdata rx_rsl_ud;

	cell_list := ts_BSSMAP_CIL_CGI({bssmap_cgi(mp_cgi_bts0)});
	f_cbsp_init_server(17001, 17501);

	f_cbsp_write_emerg(g_cbsp_msg_id, g_cbsp_ser_no, cell_list);

	/* first expect the PN to be enabled */
	var template (present) octetstring tr_apdu := f_gen_etws_pn(g_cbsp_ser_no, g_cbsp_msg_id);
	timer T := 5.0;
	T.start;
	alt {
	[] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_OSMO_ETWS_CMD(t_RslChanNr_PCH_AGCH(0), tr_apdu))) {
		setverdict(pass);
		}
	[] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_OSMO_ETWS_CMD(?,?))) {
		setverdict(fail, "Received unexpected OSMO_ETWS_CMD");
		mtc.stop;
		}
	[] IPA_RSL[0].receive { repeat; }
	[] T.timeout {
		setverdict(fail, "Timeout waiting for RSL_OSMO_ETWS_CMD (enable)");
		mtc.stop;
		}
	}

	/* then expect it to be disabled after the warning period (5s) */
	T.start;
	alt {
	[] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_OSMO_ETWS_CMD(t_RslChanNr_PCH_AGCH(0), ''O))) {
		setverdict(pass);
		}
	[] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_OSMO_ETWS_CMD(?,?))) {
		setverdict(fail, "Received unexpected OSMO_ETWS_CMD");
		mtc.stop;
		}
	[] IPA_RSL[0].receive { repeat; }
	[] T.timeout {
		setverdict(fail, "Timeout waiting for RSL_OSMO_ETWS_CMD (disable)");
		mtc.stop;
		}
	}
}



control {
	execute( TC_cbsp_bsc_server() );
	execute( TC_cbsp_bsc_client() );
	execute( TC_cbsp_reset_bss() );

	/* test various different types of Cell Identities */
	execute( TC_cbsp_write_bss() );
	execute( TC_cbsp_write_bts_cgi() );
	execute( TC_cbsp_write_bts_no_cbch() );
	execute( TC_cbsp_write_unknown_bts() );
	execute( TC_cbsp_write_lac_ci() );
	execute( TC_cbsp_write_ci() );
	execute( TC_cbsp_write_lai() );
	execute( TC_cbsp_write_lac() );

	execute( TC_cbsp_write_then_replace() );
	execute( TC_cbsp_replace_nonexist() );
	execute( TC_cbsp_write_too_many() );
	execute( TC_cbsp_kill_nonexist() );
	execute( TC_cbsp_write_then_kill() );
	execute( TC_cbsp_write_then_reset() );

	execute( TC_cbsp_emerg_write_bts_cgi_dchan() );
	execute( TC_cbsp_emerg_write_bts_cgi_cchan() );
	execute( TC_cbsp_emerg_write_bts_cgi_cchan_disable() );
}


}
