cbc: Test ETWS msg over CBSP

So far only non-emergency CBS messages were tested, which require a
slighlty idfferent encoding on the protocol side.

Related: OS#4945
Change-Id: Ie22a00120218a205db11a5622274dcc67435f5de
diff --git a/cbc/BSC_ConnectionHandler.ttcn b/cbc/BSC_ConnectionHandler.ttcn
index a8601a6..804d246 100644
--- a/cbc/BSC_ConnectionHandler.ttcn
+++ b/cbc/BSC_ConnectionHandler.ttcn
@@ -106,11 +106,20 @@
 		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);
+		if (msg_id_is_etws(msg.msg_id)) {
+			tx := ts_CBSP_WRITE_EMERG_COMPL(msg.msg_id, msg.ser_nr, tx_list);
+		} else {
+			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);
+		if (msg_id_is_etws(msg.msg_id)) {
+			tx := ts_CBSP_REPLACE_EMERG_COMPL(msg.msg_id, msg.ser_nr, msg.old_ser_nr,
+							  tx_list);
+		} 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));
 }
@@ -134,13 +143,19 @@
 	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(?, ?);
+	if (msg_id_is_etws(msg.msg_id)) {
+		rx_templ := tr_CBSP_WRITE_EMERG(msg.msg_id, msg.ser_nr, msg.cell_list, 1,
+						hex2int('180'H) + (msg.msg_id - 4352),
+						msg.num_bcast_req, 0)
+	} else {
+		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);
 	}
-	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;
diff --git a/cbc/CBC_Tests.ttcn b/cbc/CBC_Tests.ttcn
index fdf3b0f..581298a 100644
--- a/cbc/CBC_Tests.ttcn
+++ b/cbc/CBC_Tests.ttcn
@@ -653,6 +653,25 @@
 	f_shutdown_helper();
 }
 
+/* Test ETWS message. TS 23.041 9.4.1.2.2 */
+testcase TC_ecbe_create_delete_etws_bsc() runs on test_CT {
+	f_init(num_bsc := 1);
+	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list_success;
+	var template (value) CBS_Message msg := t_CBSmsg(4352 /* Earthquake */, 16752);
+	msg.channel_ind := omit;
+
+	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)
+	});
+	g_pars_BSC[0].start_fn := refers(f_bsc_create_and_delete);
+	g_pars_BSC[0].exp_cbs_msg := valueof(msg);
+	g_pars_BSC[0].cell_list_success := valueof(cell_list_success);
+	f_start();
+	f_create_and_delete(valueof(msg));
+	f_shutdown_helper();
+}
+
 control {
 	execute( TC_rx_keepalive() );
 	execute( TC_rx_keepalive_timeout() );
@@ -667,6 +686,8 @@
 	execute( TC_ecbe_create_delete_bsc_server() );
 	execute( TC_ecbe_create_delete_mme_server() );
 	execute( TC_concurrent_cbs_msg_mme() );
+
+	execute( TC_ecbe_create_delete_etws_bsc() );
 }
 
 }
diff --git a/cbc/CBS_Message.ttcn b/cbc/CBS_Message.ttcn
index 1ce6935..faaa403 100644
--- a/cbc/CBS_Message.ttcn
+++ b/cbc/CBS_Message.ttcn
@@ -26,7 +26,7 @@
 	uint16_t ser_nr,
 	uint16_t old_ser_nr optional,
 	BSSMAP_FIELD_CellIdentificationList cell_list,
-	uint8_t channel_ind,
+	uint8_t channel_ind optional,
 	CBSP_Category category,
 	uint16_t rep_period,
 	uint16_t num_bcast_req,
@@ -39,4 +39,12 @@
 };
 type record of CBS_MessageContent CBS_MessageContents;
 
+function msg_id_is_etws(uint16_t msg_id) return boolean
+{
+	if (msg_id >= 4352 and msg_id <= 4359) {
+		return true;
+	}
+	return false;
+}
+
 }
diff --git a/cbc/ECBE_Components.ttcn b/cbc/ECBE_Components.ttcn
index eaf2772..996b17d 100644
--- a/cbc/ECBE_Components.ttcn
+++ b/cbc/ECBE_Components.ttcn
@@ -35,9 +35,44 @@
 	return hex2str(oct2hex(inp.payload));
 }
 
+private function f_cbs2ecbe_etws(CBS_Message inp, charstring cbe_name) return EcbeCbcMessage
+{
+	var EcbeWarningTypeDecoded warn_type;
+	int2enum(inp.msg_id - 4352, warn_type);
+
+	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_etws := {
+					warning_type := {
+						warning_type_decoded := warn_type
+					},
+					emergency_user_alert := true,
+					popup_on_display := true,
+					warning_sec_info := omit
+					}
+			}
+		}
+	};
+	return ret;
+}
+
 /* convert from CBS_Message to EcbeCbcMessage */
 function f_cbs2ecbe(CBS_Message inp, charstring cbe_name) return EcbeCbcMessage
 {
+	if (msg_id_is_etws(inp.msg_id)) {
+		return f_cbs2ecbe_etws(inp, cbe_name);
+	}
+
 	var EcbeCbcMessage ret := {
 		cbe_name := cbe_name,
 		category := f_cbs2ecbe_category(inp.category),
diff --git a/library/CBSP_Templates.ttcn b/library/CBSP_Templates.ttcn
index 6ff2742..bcbb7be 100644
--- a/library/CBSP_Templates.ttcn
+++ b/library/CBSP_Templates.ttcn
@@ -381,6 +381,19 @@
 	ies[lengthof(ies)] := ts_CbspChannelInd(channel_ind);
 	return ts_CBSP(CBSP_MSGT_WRITE_REPLACE_COMPL, ies);
 }
+function ts_CBSP_WRITE_EMERG_COMPL(uint16_t msg_id, uint16_t new_ser_nr,
+				 template (omit) BSSMAP_FIELD_CellIdentificationList cell_list)
+return template (value) CBSP_PDU {
+	var template (value) CBSP_IEs ies := {
+		ts_CbspMsgId(msg_id),
+		ts_NewSerNo(new_ser_nr)
+	};
+	if (not istemplatekind(cell_list, "omit")) {
+		ies[lengthof(ies)] := ts_CbspCellList(valueof(cell_list));
+	}
+	return ts_CBSP(CBSP_MSGT_WRITE_REPLACE_COMPL, ies);
+}
+
 function tr_CBSP_WRITE_CBS_COMPL(template uint16_t msg_id, template uint16_t new_ser_nr,
 				 template BSSMAP_FIELD_CellIdentificationList cell_list,
 				 template uint8_t channel_ind)
@@ -397,8 +410,23 @@
 	} else if (not istemplatekind(cell_list, "omit")) {
 		ies[lengthof(ies)] := tr_CbspCellList(cell_list);
 	}
-	if (not istemplatekind(channel_ind, "omit")) {
-		ies[lengthof(ies)] := tr_CbspChannelInd(channel_ind);
+	ies[lengthof(ies)] := tr_CbspChannelInd(channel_ind);
+	return tr_CBSP(CBSP_MSGT_WRITE_REPLACE_COMPL, ies);
+}
+function tr_CBSP_WRITE_EMERG_COMPL(template uint16_t msg_id, template uint16_t new_ser_nr,
+				 template BSSMAP_FIELD_CellIdentificationList cell_list)
+return template CBSP_PDU {
+	var template CBSP_IEs ies := {
+		tr_CbspMsgId(msg_id),
+		tr_NewSerNo(new_ser_nr)
+	};
+	if (istemplatekind(cell_list, "*")) {
+		testcase.stop("TITAN > 6.5.0 doesn't support this");
+		//ies[lengthof(ies)] := tr_CbspCellList ifpresent;
+	} else if (istemplatekind(cell_list, "?")) {
+		ies[lengthof(ies)] := tr_CbspCellList(?);
+	} else if (not istemplatekind(cell_list, "omit")) {
+		ies[lengthof(ies)] := tr_CbspCellList(cell_list);
 	}
 	return tr_CBSP(CBSP_MSGT_WRITE_REPLACE_COMPL, ies);
 }
@@ -421,6 +449,19 @@
 	ies[lengthof(ies)] := ts_CbspChannelInd(channel_ind);
 	return ts_CBSP(CBSP_MSGT_WRITE_REPLACE_COMPL, ies);
 }
+function ts_CBSP_REPLACE_EMERG_COMPL(uint16_t msg_id, uint16_t new_ser_nr, uint16_t old_ser_nr,
+				   template (omit) BSSMAP_FIELD_CellIdentificationList cell_list)
+return template (value) CBSP_PDU {
+	var template (value) CBSP_IEs ies := {
+		ts_CbspMsgId(msg_id),
+		ts_NewSerNo(new_ser_nr),
+		ts_OldSerNo(old_ser_nr)
+	};
+	if (not istemplatekind(cell_list, "omit")) {
+		ies[lengthof(ies)] := ts_CbspCellList(valueof(cell_list));
+	}
+	return ts_CBSP(CBSP_MSGT_WRITE_REPLACE_COMPL, ies);
+}
 function tr_CBSP_REPLACE_CBS_COMPL(template uint16_t msg_id, template uint16_t new_ser_nr,
 				   template uint16_t old_ser_nr,
 				   template CBSP_IE_NumBcastComplList compl_list,
@@ -454,6 +495,26 @@
 	}
 	return tr_CBSP(CBSP_MSGT_WRITE_REPLACE_COMPL, ies);
 }
+function tr_CBSP_REPLACE_EMERG_COMPL(template uint16_t msg_id, template uint16_t new_ser_nr,
+				   template uint16_t old_ser_nr,
+				   template BSSMAP_FIELD_CellIdentificationList cell_list)
+return template CBSP_PDU {
+	var template CBSP_IEs ies := {
+		tr_CbspMsgId(msg_id),
+		tr_NewSerNo(new_ser_nr),
+		tr_OldSerNo(old_ser_nr)
+	};
+
+	if (istemplatekind(cell_list, "*")) {
+		testcase.stop("TITAN > 6.5.0 doesn't support this");
+		//ies[lengthof(ies)] := tr_CbspCellList ifpresent;
+	} else if (istemplatekind(cell_list, "?")) {
+		ies[lengthof(ies)] := tr_CbspCellList(?);
+	} else if (not istemplatekind(cell_list, "omit")) {
+		ies[lengthof(ies)] := tr_CbspCellList(cell_list);
+	}
+	return tr_CBSP(CBSP_MSGT_WRITE_REPLACE_COMPL, ies);
+}
 
 
 /* 8.1.3.3 WRITE-REPLACE FAILURE */