cbc: Support mme/bsc sctp/tcp server mode

Related: OS#4945
Change-Id: I9fa4ddfa18ac85644f219874e6b2166e1795e3a9
diff --git a/cbc/CBC_Tests.ttcn b/cbc/CBC_Tests.ttcn
index 64cf5e2..406baed 100644
--- a/cbc/CBC_Tests.ttcn
+++ b/cbc/CBC_Tests.ttcn
@@ -33,18 +33,38 @@
 import from BSC_ConnectionHandler all;
 import from MME_ConnectionHandler all;
 
+const integer MAX_BSC := 2;
+const integer MAX_MME := 2;
+
+type record BSC_modulepar_cfg {
+	boolean tcp_is_client
+};
+type record of BSC_modulepar_cfg BSC_modulepar_cfgs;
+
+type record MME_modulepar_cfg {
+	boolean sctp_is_client
+};
+type record of MME_modulepar_cfg MME_modulepar_cfgs;
+
 modulepar {
+	charstring mp_local_host := "127.0.0.2";
 	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 := 15000;
 	integer mp_local_sbcap_port := 16000;
+	/* Must match osmo-cbc.cfg: */
+	BSC_modulepar_cfgs mp_bsc_cfg := {
+		{ tcp_is_client := true },
+		{ tcp_is_client := false }
+	};
+	MME_modulepar_cfgs mp_mme_cfg := {
+		{ sctp_is_client := true },
+		{ sctp_is_client := false }
+	};
 };
 
-const integer MAX_BSC := 3;
-const integer MAX_MME := 3;
-
 type component test_CT extends CBSP_Adapter_CT, http_CT {
 	timer g_Tguard := 60.0;
 	var integer g_num_bsc;
@@ -53,6 +73,8 @@
 	var MME_ConnHdlr g_vc_conn_MME[MAX_MME];
 	var BSC_ConnHdlrPars g_pars_BSC[MAX_BSC];
 	var MME_ConnHdlrPars g_pars_MME[MAX_MME];
+	port BSC_ConnHdlr_Coord_PT COORD_BSC[MAX_BSC];
+	port MME_ConnHdlr_Coord_PT COORD_MME[MAX_BSC];
 };
 
 private function f_shutdown_helper() runs on test_CT {
@@ -84,12 +106,16 @@
 private function f_BSC_ConnHdlr_start_fn_void() runs on BSC_ConnHdlr {
 	log("Default start_fn() function called!");
 }
-private function f_init_pars_bsc(integer bsc_cbsp_port, charstring cbc_host, integer cbc_cbsp_port)
+private function f_init_pars_bsc(charstring bsc_host, integer bsc_cbsp_port,
+				 charstring cbc_host, integer cbc_cbsp_port,
+				 boolean tcp_is_client)
 		runs on test_CT return BSC_ConnHdlrPars {
 	var BSC_ConnHdlrPars pars := {
+		bsc_host := bsc_host,
 		bsc_cbsp_port := bsc_cbsp_port,
 		cbc_host := cbc_host,
 		cbc_cbsp_port := cbc_cbsp_port,
+		tcp_is_client := tcp_is_client,
 		start_fn := refers(f_BSC_ConnHdlr_start_fn_void),
 		exp_cbs_msg := omit,
 		cell_list_success := omit
@@ -101,7 +127,10 @@
 	var BSC_ConnHdlr vc_conn;
 	id := id & "-BSC" & int2str(idx);
 	vc_conn := BSC_ConnHdlr.create(id) alive;
-	g_pars_BSC[idx] := f_init_pars_bsc(mp_local_cbsp_port + idx, mp_cbc_host, mp_cbc_cbsp_port);
+	g_pars_BSC[idx] := f_init_pars_bsc(mp_local_host, mp_local_cbsp_port + idx,
+					   mp_cbc_host, mp_cbc_cbsp_port,
+					   mp_bsc_cfg[idx].tcp_is_client);
+	connect(self:COORD_BSC[idx], vc_conn:COORD);
 	return vc_conn;
 }
 
@@ -118,12 +147,16 @@
 private function f_MME_ConnHdlr_start_fn_void() runs on MME_ConnHdlr {
 	log("Default start_fn() function called!");
 }
-private function f_init_pars_mme(integer mme_sbcap_port, charstring cbc_host, integer cbc_sbcap_port)
+private function f_init_pars_mme(charstring mme_host, integer mme_sbcap_port,
+				 charstring cbc_host, integer cbc_sbcap_port,
+				 boolean sctp_is_client)
 		runs on test_CT return MME_ConnHdlrPars {
 	var MME_ConnHdlrPars pars := {
+		mme_host := mme_host,
 		mme_sbcap_port := mme_sbcap_port,
 		cbc_host := cbc_host,
 		cbc_sbcap_port := cbc_sbcap_port,
+		sctp_is_client := sctp_is_client,
 		start_fn := refers(f_MME_ConnHdlr_start_fn_void),
 		exp_cbs_msg := omit,
 		write_replace_warning_ind_cause := omit,
@@ -136,7 +169,10 @@
 	var MME_ConnHdlr vc_conn;
 	id := id & "-MME" & int2str(idx);
 	vc_conn := MME_ConnHdlr.create(id) alive;
-	g_pars_MME[idx] := f_init_pars_mme(mp_local_sbcap_port + idx, mp_cbc_host, mp_cbc_sbcap_port);
+	g_pars_MME[idx] := f_init_pars_mme(mp_local_host, mp_local_sbcap_port + idx,
+					   mp_cbc_host, mp_cbc_sbcap_port,
+					   mp_mme_cfg[idx].sctp_is_client);
+	connect(self:COORD_MME[idx], vc_conn:COORD);
 	return vc_conn;
 }
 
@@ -172,7 +208,14 @@
 	for (var integer i := 0; i < g_num_mme; i := i + 1) {
 		f_start_mme(i, testcasename(), g_pars_MME[i]);
 	}
-	f_sleep(2.0); /* wait all conns connected */
+
+	/* Now wait for conns to be ready: */
+	for (var integer i := 0; i < g_num_bsc; i := i + 1) {
+		COORD_BSC[i].receive(COORD_MSG_CONNECTED);
+	}
+	for (var integer i := 0; i < g_num_mme; i := i + 1) {
+		COORD_MME[i].receive(COORD_MSG_CONNECTED);
+	}
 }
 
 /* test whether or not we receive a valid KEEP-ALIVE from the CBC */
@@ -483,6 +526,56 @@
 	f_shutdown_helper();
 }
 
+/* Create and delete message with BSC acting as TCP server */
+testcase TC_ecbe_create_delete_bsc_server() runs on test_CT {
+	var template (value) BSSMAP_FIELD_CellIdentificationList cell_list_success;
+	var template (value) CBS_Message msg := t_CBSmsg(46, 16752);
+
+	/* The 2nd BSC is the one configured as server, but we only want to test
+	 * that one, so initialize both but copy over config of the 2nd one to
+	 * the first one, to start only one BSC: */
+	f_init(num_bsc := 2);
+	g_num_bsc := 1;
+	g_pars_BSC[0] := g_pars_BSC[1];
+
+	cell_list_success := ts_BSSMAP_CIL_CI({
+		ts_BSSMAP_CI_CI(50001),
+		ts_BSSMAP_CI_CI(50002),
+		ts_BSSMAP_CI_CI(50003)
+	});
+	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();
+}
+
+/* Create and delete message with MME acting as SCTP server */
+testcase TC_ecbe_create_delete_mme_server() runs on test_CT {
+	var template (value) CellId_Broadcast_List bcast_cell_id_li;
+	var template (value) CBS_Message msg := t_CBSmsg(48, 16752);
+
+	/* The 2nd MME is the one configured as server, but we only want to test
+	 * that one, so initialize both but copy over config of the 2nd one to
+	 * the first one, to start only one MME: */
+	f_init(num_bsc := 0, num_mme := 2);
+	g_num_mme := 1;
+	g_pars_MME[0] := g_pars_MME[1];
+
+	bcast_cell_id_li := {
+		ts_SBCAP_CellId_Broadcast_List_Item(ts_SBCAP_ECGI(f_enc_mcc_mnc('901'H, '70'H), 1234)),
+		ts_SBCAP_CellId_Broadcast_List_Item(ts_SBCAP_ECGI(f_enc_mcc_mnc('901'H, '70'H), 5678))
+	};
+	g_pars_MME[0].start_fn := refers(f_mme_create_and_delete);
+	g_pars_MME[0].exp_cbs_msg := valueof(msg);
+	g_pars_MME[0].write_replace_warning_ind_cause := SBC_AP_Cause_message_accepted;
+	g_pars_MME[0].bcast_cell_id_list := valueof(bcast_cell_id_li);
+	f_start();
+	f_create_and_delete(valueof(msg));
+	f_shutdown_helper();
+}
+
 control {
 	execute( TC_rx_keepalive() );
 	execute( TC_rx_keepalive_timeout() );
@@ -493,6 +586,8 @@
 	execute( TC_ecbe_create_delete_lai() );
 	execute( TC_ecbe_create_delete_mme_indication() );
 	execute( TC_ecbe_create_delete_bsc_and_mme() );
+	execute( TC_ecbe_create_delete_bsc_server() );
+	execute( TC_ecbe_create_delete_mme_server() );
 }
 
 }