bsc: Increase test coverage for CBSP emergency broadcasts

This adds new tests:
* TC_cbsp_emerg_write_bts_cgi_noreplace
* TC_cbsp_emerg_write_bts_cgi_replace
* TC_cbsp_emerg_write_bts_cgi_kill

All of the above relate to improved / fixed handling of emergency
broadcasts in some corner cases.

Related: SYS#5906
Related: OS#5539, OS#5540
Change-Id: Ic0f0b3d620f3ca73bab3d45997d0c1b9433ac1f7
diff --git a/bsc/BSC_Tests_CBSP.ttcn b/bsc/BSC_Tests_CBSP.ttcn
index 48769aa..bede026 100644
--- a/bsc/BSC_Tests_CBSP.ttcn
+++ b/bsc/BSC_Tests_CBSP.ttcn
@@ -320,6 +320,36 @@
 	}
 }
 
+/* send a REPLACE emergency to the BSC; expect either COMPLETE or FAILURE in response*/
+function f_cbsp_replace_emerg(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) 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_REPLACE_EMERG(msg_id, new_ser_no, old_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_REPLACE_CBS_COMPL(msg_id, new_ser_no, old_ser_no, omit, success_list, omit);
+	} else {
+		rx := tr_CBSP_REPLACE_CBS_FAIL(msg_id, new_ser_no, old_ser_no, fail_list, omit, 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 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,
@@ -933,9 +963,80 @@
 	f_exp_rsl_etws(0, false);
 }
 
+/* Write (!replace) ETWS PN to a single BTS which already has an ongoing PN; expect failure (OS#5539) */
+testcase TC_cbsp_emerg_write_bts_cgi_noreplace() 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;
+
+	g_pars := valueof(ts_CBSP_Pars_default(false, 18001, 18501));
+	f_init();
+
+	cell_list := ts_BSSMAP_CIL_CGI({bssmap_cgi(mp_cgi_bts0)});
+	f_cbsp_write_emerg(g_cbsp_msg_id, g_cbsp_ser_no, cell_list);
+
+	/* first expect the PN to be enabled */
+	f_exp_rsl_etws(0, true);
+
+	/* write another emergency while first one is still ongoing; expect it to fail */
+	f_cbsp_write_emerg(g_cbsp_msg_id, g_cbsp_ser_no+1, cell_list, success_list:=omit, fail_list:=?);
+
+	/* then expect first one to be disabled after the warning period (5s) */
+	f_exp_rsl_etws(0, false);
+
+	/* write another emergency after the first one has expired; expect it to succeed */
+	g_cbsp_ser_no := g_cbsp_ser_no + 2;
+	f_cbsp_write_emerg(g_cbsp_msg_id, g_cbsp_ser_no, cell_list, success_list:=?, fail_list:=omit);
+	f_exp_rsl_etws(0, true);
+}
+
+/* Replace ETWS PN to a single BTS which already has an ongoing PN; expect success */
+testcase TC_cbsp_emerg_write_bts_cgi_replace() 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;
+
+	g_pars := valueof(ts_CBSP_Pars_default(false, 19001, 19501));
+	f_init();
+
+	cell_list := ts_BSSMAP_CIL_CGI({bssmap_cgi(mp_cgi_bts0)});
+	f_cbsp_write_emerg(g_cbsp_msg_id, g_cbsp_ser_no, cell_list);
+
+	/* first expect the PN to be enabled */
+	f_exp_rsl_etws(0, true);
+
+	/* write another emergency while first one is still ongoing; expect it to fail */
+	f_cbsp_replace_emerg(g_cbsp_msg_id, g_cbsp_ser_no+1, g_cbsp_ser_no, cell_list);
+}
+
+/* Write ETWS PN to a single BTS, then kill it during its lifetime (OS#5540) */
+testcase TC_cbsp_emerg_write_bts_cgi_kill() 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;
+
+	g_pars := valueof(ts_CBSP_Pars_default(false, 20001, 20501));
+	f_init();
+
+	cell_list := ts_BSSMAP_CIL_CGI({bssmap_cgi(mp_cgi_bts0)});
+	f_cbsp_write_emerg(g_cbsp_msg_id, g_cbsp_ser_no, cell_list, warn_per := 10);
+
+	/* first expect the PN to be enabled */
+	f_exp_rsl_etws(0, true);
+
+	/* kill it; expect non-zero success list, and no completion or failure lists */
+	f_cbsp_kill(g_cbsp_msg_id, g_cbsp_ser_no, omit, cell_list, success_list:=cell_list,
+		    compl_list:=omit, fail_list:=omit);
+
+	/* then expect it to be disabled */
+	f_exp_rsl_etws(0, false);
+}
+
+
+
 /* Send a MSG STATUS QUERY for an unknown message; expect no completion list and present failure list */
 testcase TC_cbsp_status_q_empty() runs on cbsp_test_CT {
-	g_pars := valueof(ts_CBSP_Pars_default(false, 18001, 18501));
+	g_pars := valueof(ts_CBSP_Pars_default(false, 21001, 21501));
 	f_init();
 
 	f_cbsp_msg_status_query(g_cbsp_msg_id, g_cbsp_ser_no, compl_list := omit, fail_list := ?);
@@ -943,7 +1044,7 @@
 
 /* Send a SMSCB to entire BSS followed by MSG_STATUS_QUERY; expect completion list and no failure list */
 testcase TC_cbsp_status_q_bts_cgi() runs on cbsp_test_CT {
-	g_pars := valueof(ts_CBSP_Pars_default(false, 19001, 19501));
+	g_pars := valueof(ts_CBSP_Pars_default(false, 22001, 22501));
 	f_init();
 
 	var CBSP_IEs pages := {f_gen_page()};
@@ -1005,6 +1106,9 @@
 	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() );
+	execute( TC_cbsp_emerg_write_bts_cgi_noreplace() );
+	execute( TC_cbsp_emerg_write_bts_cgi_replace() );
+	execute( TC_cbsp_emerg_write_bts_cgi_kill() );
 }
 
 
diff --git a/library/CBSP_Templates.ttcn b/library/CBSP_Templates.ttcn
index 17d933a..d166bcf 100644
--- a/library/CBSP_Templates.ttcn
+++ b/library/CBSP_Templates.ttcn
@@ -314,7 +314,6 @@
 						template (value) BSSMAP_FIELD_CellIdentificationList cell_list,
 						template (value) uint8_t emerg_ind,
 						template (value) uint16_t warn_type,
-						template (value) uint16_t num_bcast_req,
 						template (value) uint8_t warn_per
 					    ) :=
 	ts_CBSP(CBSP_MSGT_WRITE_REPLACE, {
@@ -331,7 +330,6 @@
 					template BSSMAP_FIELD_CellIdentificationList cell_list := ?,
 					template uint8_t emerg_ind := ?,
 					template uint16_t warn_type := ?,
-					template uint16_t num_bcast_req := ?,
 					template uint8_t warn_per := ?
 				    ) :=
 	tr_CBSP(CBSP_MSGT_WRITE_REPLACE, {
@@ -541,15 +539,21 @@
 }
 
 /* 8.1.3.4 KILL */
-template (value) CBSP_PDU ts_CBSP_KILL(template (value) uint16_t msg_id,
-					template (value) uint16_t old_ser_nr,
-					template (value) BSSMAP_FIELD_CellIdentificationList cell_list,
-					template (omit) uint8_t channel_ind) :=
-	ts_CBSP(CBSP_MSGT_KILL, {
-			ts_CbspMsgId(msg_id),
-			ts_OldSerNo(old_ser_nr),
-			ts_CbspCellList(cell_list),
-			ts_CbspChannelInd(channel_ind)});
+function ts_CBSP_KILL(template (value) uint16_t msg_id,
+			template (value) uint16_t old_ser_nr,
+			template (value) BSSMAP_FIELD_CellIdentificationList cell_list,
+			template (omit) uint8_t channel_ind)
+return template (value) CBSP_PDU {
+	var template (value) CBSP_IEs ies := {
+		ts_CbspMsgId(msg_id),
+		ts_OldSerNo(old_ser_nr),
+		ts_CbspCellList(cell_list)
+	};
+	if (not istemplatekind(channel_ind, "omit")) {
+		ies[lengthof(ies)] := ts_CbspChannelInd(channel_ind);
+	}
+	return ts_CBSP(CBSP_MSGT_KILL, ies);
+}
 function tr_CBSP_KILL(template uint16_t msg_id := ?, template uint16_t old_ser_nr := ?,
 			template BSSMAP_FIELD_CellIdentificationList cell_list := ?,
 			template uint8_t channel_ind := ?)