module CBC_Tests {

import from Osmocom_Types all;
import from Socket_API_Definitions all;

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

import from SBC_AP_IEs all;
import from SBC_AP_Constants all;
import from SBC_AP_PDU_Contents all;
import from SBC_AP_PDU_Descriptions all;
import from SBC_AP_Types all;
import from SBC_AP_Templates all;
import from SBC_AP_CodecPort all;
import from SBC_AP_Adapter all;

import from HTTP_Adapter all;
import from HTTPmsg_Types all;
import from ECBE_Types all;

modulepar {
	charstring mp_cbc_host := "127.0.0.1";
	integer mp_cbc_cbsp_port := 48049;
	integer mp_cbc_sbcap_port := c_SBC_AP_PORT;
	integer mp_cbc_ecbe_port := 12345;
	integer mp_local_cbsp_port := 9999;
	integer mp_local_sbcap_port := 9998;
};

type component test_CT extends CBSP_Adapter_CT, SBC_AP_Adapter_CT, http_CT {
};

/*********************************************************************************
 * ECBE (REST) interface
 *********************************************************************************/

function f_ecbe_tx_post_cbs(EcbeCbcMessage cbc)
runs on http_CT {
	var charstring body := oct2char(enc_EcbeCbcMessage(cbc));
	log("TX POST CBS: ", body);
	var HTTPMessage http_resp;
	f_http_tx_request(url := "/api/ecbe/v1/message", method := "POST", body := body);
}

function f_ecbe_rx_resp(template integer exp_sts := (200..299))
runs on http_CT return HTTPResponse {
	var HTTPMessage http_resp := f_http_rx_response(tr_HTTP_Resp(exp_sts), tout := 20.0);
	return http_resp.response;
}

/* run a HTTP POST to add a new CBC message */
function f_ecbe_post_cbs(EcbeCbcMessage cbc, template integer exp_sts := 201)
runs on http_CT return HTTPResponse {
	f_ecbe_tx_post_cbs(cbc);
	return f_ecbe_rx_resp(exp_sts)
}

function f_ecbe_tx_delete_cbs(integer msg_id)
runs on http_CT {
	f_http_tx_request("/api/ecbe/v1/message/" & int2str(msg_id), method := "DELETE");
}

/* run a HTTP GET on specified URL expecting json in RSRES format as response */
function f_ecbe_delete_cbs(integer msg_id, template integer exp_sts := 200)
runs on http_CT return HTTPResponse {
	f_ecbe_tx_delete_cbs(msg_id);
	return f_ecbe_rx_resp(exp_sts);
}


altstep as_cbsp_reset(integer idx) runs on CBSP_Adapter_CT {
	var CBSP_RecvFrom rf;
	[] CBSP[idx].receive(tr_CBSP_Recv(g_cbsp_conn_id[idx], tr_CBSP_RESET)) -> value rf {
		var CBSP_IE ie;
		f_cbsp_find_ie(rf.msg, CBSP_IEI_CELL_LIST, ie);
		CBSP[idx].send(ts_CBSP_Send(g_cbsp_conn_id[idx],
				ts_CBSP_RESET_COMPL(ie.body.cell_list.cell_id)));
	}
}

private function f_cbs2ecbe_category(CBSP_Category cat_in) return EcbeCategory
{
	select (cat_in) {
	case (CBSP_CATEG_HIGH_PRIO) { return high_priority; }
	case (CBSP_CATEG_BACKGROUND) { return background; }
	case (CBSP_CATEG_NORMAL) { return normal; }
	case else { mtc.stop }
	}
}

private function f_cbs2ecbe_page(CBS_MessageContent inp) return EcbePage
{
	return hex2str(oct2hex(inp.payload));
}

/* convert from CBS_Message to EcbeCbcMessage */
function f_cbs2ecbe(CBS_Message inp, charstring cbe_name) return EcbeCbcMessage
{
	var EcbeCbcMessage ret := {
		cbe_name := cbe_name,
		category := f_cbs2ecbe_category(inp.category),
		repetition_period := inp.rep_period,
		num_of_bcast := inp.num_bcast_req,
		scope := { scope_plmn := {} },
		smscb_message := {
			serial_nr := {
				serial_nr_encoded := inp.ser_nr
			},
			message_id := inp.msg_id,
			payload := {
				payload_encoded := {
					dcs := inp.dcs,
					pages := { } /* appended below */
					}
			}
		}
	};
	for (var integer i := 0; i < lengthof(inp.content); i := i+1) {
		ret.smscb_message.payload.payload_encoded.pages :=
			ret.smscb_message.payload.payload_encoded.pages & { f_cbs2ecbe_page(inp.content[i]) };
	}
	return ret;
}

/*********************************************************************************
 * CBSP interface
 *********************************************************************************/

/* receive + acknowledge KEEP-ALIVE */
altstep as_cbsp_keepalive_ack(integer idx) runs on CBSP_Adapter_CT {
	[] CBSP[idx].receive(tr_CBSP_Recv(g_cbsp_conn_id[idx], tr_CBSP_KEEP_ALIVE)) {
		CBSP[idx].send(ts_CBSP_Send(g_cbsp_conn_id[idx], ts_CBSP_KEEP_ALIVE_COMPL));
	}
}

/* receive + ignore RESTART */
altstep as_cbsp_restart(integer idx) runs on CBSP_Adapter_CT {
	[] CBSP[idx].receive(tr_CBSP_Recv(g_cbsp_conn_id[idx], tr_CBSP_RESTART));
}

private function f_shutdown_helper() runs on test_CT {
	all component.stop;
	setverdict(pass);
	mtc.stop;
}

private function f_init(boolean raw := false) runs on test_CT {
	f_http_init(mp_cbc_host, mp_cbc_ecbe_port);
	CBSP_Adapter.f_connect(mp_cbc_host, mp_cbc_cbsp_port, "", mp_local_cbsp_port);
	SBC_AP_Adapter.f_connect(mp_cbc_host, mp_cbc_sbcap_port, "", mp_local_sbcap_port);

	if (not raw) {
		var BSSMAP_FIELD_CellIdentificationList cell_list := {
			cIl_allInBSS := ''O
		};
		activate(as_cbsp_keepalive_ack(0));
		activate(as_cbsp_restart(0));
		f_cbsp_send(ts_CBSP_RESTART(cell_list, CBSP_BC_MSGT_CBS, CBSP_RI_DATA_LOST));
		f_cbsp_send(ts_CBSP_RESTART(cell_list, CBSP_BC_MSGT_EMERG, CBSP_RI_DATA_LOST));
		as_cbsp_reset(0);
	}
}

/* test whether or not we receive a valid KEEP-ALIVE from the CBC */
testcase TC_rx_keepalive() runs on test_CT {
	var CBSP_PDU rx;
	var CBSP_IE ie;

	f_init();
	rx := f_cbsp_exp(tr_CBSP_KEEP_ALIVE(?));
	f_cbsp_find_ie(rx, CBSP_IEI_KEEP_ALIVE_REP_PERIOD, ie);

	f_shutdown_helper();
}

/* test whether CBC terminates connection if KEEP-ALIVE is not answered by BSC */
testcase TC_rx_keepalive_timeout() runs on test_CT {
	var CBSP_PDU rx;
	var CBSP_IE ie;
	var integer ka_rep_per_s;

	f_init();
	rx := f_cbsp_exp(tr_CBSP_KEEP_ALIVE(?));
	f_cbsp_find_ie(rx, CBSP_IEI_KEEP_ALIVE_REP_PERIOD, ie);

	/* sleep for longer than the keep-alive period */
	ka_rep_per_s := f_cbsp_period2s(ie.body.keep_alive_rep_period);
	f_sleep(int2float(ka_rep_per_s + 5));

	/* expect the CBSP connection to be closed */
	CBSP[0].receive(PortEvent:{connClosed:=?})

	f_shutdown_helper();
}

type record CBS_Message {
	uint16_t msg_id,
	uint16_t ser_nr,
	uint16_t old_ser_nr optional,
	BSSMAP_FIELD_CellIdentificationList cell_list,
	uint8_t channel_ind,
	CBSP_Category category,
	uint16_t rep_period,
	uint16_t num_bcast_req,
	uint8_t dcs,
	CBS_MessageContents content
};
type record CBS_MessageContent {
	octetstring payload,
	uint8_t user_len
};
type record of CBS_MessageContent CBS_MessageContents;

private function f_cbsp_tx_write_compl(CBS_Message msg, integer idx := 0,
			      template (omit) BSSMAP_FIELD_CellIdentificationList tx_cell_list := omit,
			      template (omit) CBSP_IE_NumBcastComplList tx_compl_list := omit)
runs on test_CT {
	var template (value) CBSP_PDU tx;
	var template (value) BSSMAP_FIELD_CellIdentificationList tx_list;
	if (istemplatekind(tx_cell_list, "omit")) {
		/* use the "expected list" when confirming the write-replace */
		tx_list := msg.cell_list;
	} else {
		/* use an user-provided different list of cells */
		tx_list := valueof(tx_cell_list);
	}
	if (istemplatekind(tx_compl_list, "omit")) {
		tx := ts_CBSP_WRITE_CBS_COMPL(msg.msg_id, msg.ser_nr, tx_list, msg.channel_ind);
	} else {
		tx := ts_CBSP_REPLACE_CBS_COMPL(msg.msg_id, msg.ser_nr, msg.old_ser_nr,
						valueof(tx_compl_list), tx_list,
						msg.channel_ind);
	}
	CBSP[idx].send(ts_CBSP_Send(g_cbsp_conn_id[idx], tx));
}

private function f_cbsp_tx_write_fail(CBS_Message msg, integer idx := 0,
				      template (omit) BSSMAP_FIELD_CellIdentificationList tx_cell_list := omit,
				      template (omit) CBSP_FailureListItems tx_fail_list := omit)
runs on test_CT {
	var template (value) CBSP_PDU tx;
	tx := ts_CBSP_WRITE_CBS_FAIL(msg.msg_id, msg.ser_nr, valueof(tx_fail_list),
				     omit, tx_cell_list, msg.channel_ind);
	CBSP[idx].send(ts_CBSP_Send(g_cbsp_conn_id[idx], tx));
}

/* handle a CBSP-WRITE-REPLACE and respond to it with COMPLETE or FAILURE depending on arguments */
private function f_cbsp_handle_write(CBS_Message msg, integer idx := 0,
			      template (omit) BSSMAP_FIELD_CellIdentificationList tx_cell_list := omit,
			      template (omit) CBSP_FailureListItems tx_fail_list := omit,
			      template (omit) CBSP_IE_NumBcastComplList tx_compl_list := omit)
runs on test_CT {
	var template CBSP_IEs content_ies := {};
	var template (present) CBSP_PDU rx_templ;
	var CBSP_RecvFrom rf;
	for (var integer i := 0; i < lengthof(msg.content); i := i+1) {
		//content_ies[i] := tr_CbspMsgContent(msg.content[i].payload, msg.content[i].user_len);
		content_ies[i] := tr_CbspMsgContent(?, ?);
	}
	rx_templ := tr_CBSP_WRITE_CBS(msg.msg_id, msg.ser_nr, msg.cell_list, msg.channel_ind,
				      msg.category, msg.rep_period, msg.num_bcast_req, msg.dcs,
				      content_ies);
	alt {
	[] CBSP[idx].receive(tr_CBSP_Recv(g_cbsp_conn_id[idx], rx_templ)) -> value rf {
		var template (value) CBSP_PDU tx;
		if (istemplatekind(tx_fail_list, "omit")) {
			f_cbsp_tx_write_compl(msg, idx, tx_cell_list, tx_compl_list);
		} else {
			f_cbsp_tx_write_fail(msg, idx, tx_cell_list, tx_fail_list);
		}
		}
	[] as_cbsp_keepalive_ack(idx) { repeat; }
	[] CBSP[idx].receive {
		setverdict(fail, "Received unexpected CBSP in index ", idx);
		}
	}
}

/* handle a CBSP-KILL and respond to it with COMPLETE or FAILURE depending on arguments */
private function f_cbsp_handle_kill(integer idx, uint16_t msg_id, uint16_t ser_nr,
				    template BSSMAP_FIELD_CellIdentificationList exp_list,
				    template (omit) BSSMAP_FIELD_CellIdentificationList tx_list,
				    template (omit) CBSP_FailureListItems tx_fail_list := omit,
				    template (omit) CBSP_IE_NumBcastComplList tx_compl_list := omit,
				    template (omit) uint8_t channel_ind := omit)
runs on test_CT {
	var template (present) CBSP_PDU rx_templ;
	var CBSP_RecvFrom rf;

	rx_templ := tr_CBSP_KILL(msg_id, ser_nr, exp_list, channel_ind);
	alt {
	[] CBSP[idx].receive(tr_CBSP_Recv(g_cbsp_conn_id[idx], rx_templ)) -> value rf {
		var template (value) CBSP_PDU tx;
		if (istemplatekind(tx_fail_list, "omit")) {
			tx := ts_CBSP_KILL_COMPL(msg_id, ser_nr, tx_compl_list, tx_list, channel_ind);
		} else {
			tx := ts_CBSP_KILL_FAIL(msg_id, ser_nr, valueof(tx_fail_list), tx_compl_list,
						tx_list, channel_ind);
		}
		CBSP[idx].send(ts_CBSP_Send(g_cbsp_conn_id[idx], tx));
		}
	[] as_cbsp_keepalive_ack(idx) { repeat; }
	[] CBSP[idx].receive {
		setverdict(fail, "Received unexpected CBSP in index ", idx);
		}
	}
}

private function f_sbcap_tx_write_replace_warn_resp(CBS_Message msg, integer idx := 0)
runs on test_CT {
	var template (value) SBC_AP_PDU tx;
	/* TODO: pass Unknown Tracking Area List as parameter above (omit by default) */
	tx := ts_SBCAP_WRITE_WARNING_RESP(int2bit(msg.msg_id, 16),
					  int2bit(msg.ser_nr, 16));
	f_SBC_AP_send(tx, idx);
}

private function f_sbcap_tx_stop_warn_resp(integer idx := 0, CBS_Message msg)
runs on test_CT {
	var template (value) SBC_AP_PDU tx;
	tx := ts_SBCAP_STOP_WARNING_RESP(int2bit(msg.msg_id, 16),
					  int2bit(msg.ser_nr, 16));
	f_SBC_AP_send(tx, idx);
}

/* handle a SBc-AP Write-Replace Request and respond to it with Response or FAILURE depending on arguments */
private function f_sbcap_handle_write_replace_warn_req(CBS_Message msg, integer idx := 0,
			      template (omit) BSSMAP_FIELD_CellIdentificationList tx_cell_list := omit)
runs on test_CT {
	var template (present) SBC_AP_PDU rx_templ;
	var SBC_AP_RecvFrom rf;
	rx_templ := tr_SBCAP_WRITE_WARNING(int2bit(msg.msg_id, 16),
					   int2bit(msg.ser_nr, 16),
					   msg.rep_period,
					   msg.num_bcast_req);
	alt {
	[] SBC_AP[idx].receive(tr_SBC_AP_Recv(g_cbsp_conn_id[idx], rx_templ)) -> value rf {
		var template (value) SBC_AP_PDU tx;
		log ("received expected req:", rf);
		f_sbcap_tx_write_replace_warn_resp(msg, idx);
		}
	[] SBC_AP[idx].receive {
		setverdict(fail, "Received unexpected SBc-AP in index ", idx);
		}
	}
}

/* handle a SBc-AP Stop-Warning-Request and respond to it with Response or FAILURE depending on arguments */
private function f_sbcap_handle_stop_warn_req(integer idx := 0, CBS_Message msg)
runs on test_CT {
	var template (present) SBC_AP_PDU rx_templ;
	var SBC_AP_RecvFrom rf;

	rx_templ := tr_SBCAP_STOP_WARNING(int2bit(msg.msg_id, 16),
					  int2bit(msg.ser_nr, 16));
	alt {
	[] SBC_AP[idx].receive(tr_SBC_AP_Recv(g_cbsp_conn_id[idx], rx_templ)) -> value rf {
		var template (value) SBC_AP_PDU tx;
		log ("received expected req:", rf);
		f_sbcap_tx_stop_warn_resp(idx, msg);
		}
	[] SBC_AP[idx].receive {
		setverdict(fail, "Received unexpected SBc-AP in index ", idx);
		}
	}
}

private const BSSMAP_FIELD_CellIdentificationList cil_BSS := {
	cIl_allInBSS := ''O
};

testcase TC_write_replace() runs on test_CT {
	f_init();
	var CBS_Message msg := {
		msg_id := 42,
		ser_nr := 16752,
		old_ser_nr := omit,
		cell_list := cil_BSS,
		channel_ind := 0,
		category := CBSP_CATEG_NORMAL,
		rep_period := 5,
		num_bcast_req := 3,
		dcs := 1,
		content := {
			{ '00'O, 1 }
		}
	};
	f_cbsp_handle_write(msg);
	f_sleep(100.0);
	f_shutdown_helper();
}

testcase TC_selftest() runs on test_CT {
	const octetstring c_load_q := '0700000d0400080000f110012345671200'O;
	const octetstring c_load_q_compl := '0800000f0a000a0000f1100123456700001200'O;
	const octetstring c_reset := '1000000b0400080000f11001234567'O;
	const octetstring c_reset_compl := '1100000b0400080000f11001234567'O;
	const octetstring c_msg_sts_q := '0a0000130e022b0200000400080000f110012345671200'O;
	const octetstring c_msg_sts_q_fail := '0c0000140e022b0200000900090000f11001234567021200'O;
	const octetstring c_kill := '040000110e00000200000400080000f11001234567'O;
	const octetstring c_kill_fail := '060000120e00000200000900090000f1100123456702'O;
	const octetstring c_write_repl := '010000c70e022b0300300400080000f110012345671200050006000407000613020c400107f4f29c9e769f5de337b90c921d1b8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d100'O;
	const octetstring c_write_repl_compl := '020000130e022b0300300400080000f110012345671200'O;
	const octetstring c_write_repl_fail := '030000140e022b0300300900090000f110012345670d1200'O;
	const octetstring c_msg_s_q := '0a0000130e022b0200900400080000f110012345671200'O;
	const octetstring c_msg_s_q_compl := '0b0000160e022b02009008000b0000f110012345670008001200'O;
	const octetstring c_kill_compl := '050000160e022b02008008000b0000f110012345670006001200'O;

	log(dec_CBSP_PDU(c_load_q));
	log(dec_CBSP_PDU(c_load_q_compl));
	log(dec_CBSP_PDU(c_reset));
	log(dec_CBSP_PDU(c_reset_compl));
	log(dec_CBSP_PDU(c_msg_sts_q));
	log(dec_CBSP_PDU(c_msg_sts_q_fail));
	log(dec_CBSP_PDU(c_kill));
	log(dec_CBSP_PDU(c_kill_fail));
	log(dec_CBSP_PDU(c_write_repl));
	log(dec_CBSP_PDU(c_write_repl_compl));
	log(dec_CBSP_PDU(c_write_repl_fail));
	log(dec_CBSP_PDU(c_msg_s_q));
	log(dec_CBSP_PDU(c_msg_s_q_compl));
	log(dec_CBSP_PDU(c_kill_compl));
}

import from SABP_Types all;
import from SABP_Templates all;
import from SABP_IEs all;
import from SABP_PDU_Descriptions all;

testcase TC_selftest_sabp() runs on test_CT {
	const octetstring c_write := '00000080930000080006000211120007000240c0000f0010000113f0030282ec0613f0030282ec070001400100000d0002012a000900020000000400010100000056029f01b4d90d064297d9ec37e8fe96b3c9a0303bdd68341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d10012'O;

	log(dec_SABP_PDU(c_write));
	log(enc_SABP_PDU(dec_SABP_PDU(c_write)));

	var template (value) Service_Areas_List sa_list := {
		ts_SabpSai('62F224'O, '0023'O, '0042'O)
	};
	var template (value) SABP_PDU tx;

	tx := ts_SABP_Write(int2bit(1, 16), int2bit(1, 16), sa_list, 23, 42, '00000000'B, '01011010'B);
	log("Write: ", enc_SABP_PDU(valueof(tx)))

	var Service_Areas_List sa_list2 := { valueof(ts_SabpSai('62F224'O, '1000'O, '0042'O)) };
	for (var integer i := 0; i < 2500; i := i+1) {
		sa_list2 := sa_list2 & {valueof(ts_SabpSai('62F224'O, '2000'O, int2oct(i,2))) };
	}
	tx := ts_SABP_Write(int2bit(2, 16), int2bit(2, 16), sa_list2, 23, 42, '00000000'B, '01011010'B);
	log("Write: ", enc_SABP_PDU(valueof(tx)))

	tx := ts_SABP_Restart(sa_list);
	log("Restart: ", enc_SABP_PDU(valueof(tx)));
}

/*********************************************************************************
 * ECBE interface (verifying expected procedures on CBSP)
 *********************************************************************************/

function f_create_and_delete(CBS_Message msg,
			     template (omit) BSSMAP_FIELD_CellIdentificationList cell_list_success)
runs on test_CT {
	var EcbeCbcMessage ecbe := f_cbs2ecbe(msg, "TTCN-3");
	f_ecbe_tx_post_cbs(ecbe);
	f_cbsp_handle_write(msg, 0, cell_list_success);
	f_sbcap_handle_write_replace_warn_req(msg, 0);
	f_ecbe_rx_resp(201);

	f_sleep(2.0);

	f_ecbe_tx_delete_cbs(msg.msg_id);
	/* FIXME: cbc segfaults if we terminate here (if we don't wait for Connect_result? */
	f_cbsp_handle_kill(0, msg.msg_id, msg.ser_nr, exp_list:=cell_list_success, tx_list:=cell_list_success,
			   tx_fail_list:=omit, tx_compl_list:=omit, channel_ind:=msg.channel_ind);
	f_sbcap_handle_stop_warn_req(0, msg);
	f_ecbe_rx_resp(200);
}

private template (value) CBS_Message t_CBSmsg(uint16_t msg_id, uint16_t ser_nr) := {
	msg_id := msg_id,
	ser_nr := ser_nr,
	old_ser_nr := omit,
	cell_list := cil_BSS,
	channel_ind := 0,
	category := CBSP_CATEG_NORMAL,
	rep_period := 5,
	num_bcast_req := 3,
	dcs := 1,
	content := {
		{ '00'O, 1 }
	}
};

/* specify a variety of different Cell Identifier formats to extend test coverage */
testcase TC_ecbe_create_delete_cgi() runs on test_CT {
	f_init();
	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list_success;
	var template (value) CBS_Message msg := t_CBSmsg(43, 16752);

	cell_list_success := ts_BSSMAP_CIL_CGI({
		ts_BSSMAP_CI_CGI('901'H, '70'H, 23, 42),
		ts_BSSMAP_CI_CGI('901'H, '70'H, 24, 42),
		ts_BSSMAP_CI_CGI('901'H, '70'H, 24, 43)
	});
	f_create_and_delete(valueof(msg), cell_list_success);
	f_shutdown_helper();
}
testcase TC_ecbe_create_delete_lac_ci() runs on test_CT {
	f_init();
	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list_success;
	var template (value) CBS_Message msg := t_CBSmsg(44, 16752);
	cell_list_success := ts_BSSMAP_CIL_LAC_CI({
		ts_BSSMAP_CI_LAC_CI(10001, 50001),
		ts_BSSMAP_CI_LAC_CI(10002, 50002),
		ts_BSSMAP_CI_LAC_CI(10003, 50003)
	});
	f_create_and_delete(valueof(msg), cell_list_success);
	f_shutdown_helper();
}
testcase TC_ecbe_create_delete_lac() runs on test_CT {
	f_init();
	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list_success;
	var template (value) CBS_Message msg := t_CBSmsg(45, 16752);
	cell_list_success := ts_BSSMAP_CIL_LAC({
		ts_BSSMAP_CI_LAC(10001),
		ts_BSSMAP_CI_LAC(10002),
		ts_BSSMAP_CI_LAC(10003)
	});
	f_create_and_delete(valueof(msg), cell_list_success);
	f_shutdown_helper();
}
testcase TC_ecbe_create_delete_ci() runs on test_CT {
	f_init();
	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list_success;
	var template (value) CBS_Message msg := t_CBSmsg(46, 16752);
	cell_list_success := ts_BSSMAP_CIL_CI({
		ts_BSSMAP_CI_CI(50001),
		ts_BSSMAP_CI_CI(50002),
		ts_BSSMAP_CI_CI(50003)
	});
	f_create_and_delete(valueof(msg), cell_list_success);
	f_shutdown_helper();
}
testcase TC_ecbe_create_delete_lai() runs on test_CT {
	f_init();
	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list_success;
	var template (value) CBS_Message msg := t_CBSmsg(47, 16752);
	cell_list_success := ts_BSSMAP_CIL_LAI({
		ts_BSSMAP_CI_LAI('901'H, '70'H, 25),
		ts_BSSMAP_CI_LAI('901'H, '70'H, 26),
		ts_BSSMAP_CI_LAI('901'H, '70'H, 27)
	});
	f_create_and_delete(valueof(msg), cell_list_success);
	f_shutdown_helper();
}

control {
	execute( TC_rx_keepalive() );
	execute( TC_rx_keepalive_timeout() );
	execute( TC_ecbe_create_delete_cgi() );
	execute( TC_ecbe_create_delete_lac_ci() );
	execute( TC_ecbe_create_delete_lac() );
	execute( TC_ecbe_create_delete_ci() );
	execute( TC_ecbe_create_delete_lai() );
}

}
