Change in osmo-ttcn3-hacks[master]: msc: mo and mt voice call tests: add lots of missing parts

Neels Hofmeyr gerrit-no-reply at lists.osmocom.org
Fri Apr 12 03:48:11 UTC 2019


Neels Hofmeyr has uploaded this change for review. ( https://gerrit.osmocom.org/13616


Change subject: msc: mo and mt voice call tests: add lots of missing parts
......................................................................

msc: mo and mt voice call tests: add lots of missing parts

Both f_mo_call_establish() and f_mt_call_establish() were testing barely half a
voice call setup.  For example, f_mo_call_establish() used to be satisfied with
just two CRCX, but no actual RTP connections being made.

Add numerous MNCC and MGCP messages more closely resembling an actual call.

The main reason is to achieve a state that passes both current osmo-msc master
as well as the upcoming inter-MSC Handover refactoring.

Add log markers to f_*_call_*(): often when a test halts, it is not at all
clear why. With these log markers it is saner to figure out what has happened
and what hasn't.

Change-Id: I162985045bb5e129977a3a797b656e30220990df
---
M library/MGCP_Templates.ttcn
M library/MNCC_Types.ttcn
M msc/BSC_ConnectionHandler.ttcn
3 files changed, 185 insertions(+), 37 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/16/13616/1

diff --git a/library/MGCP_Templates.ttcn b/library/MGCP_Templates.ttcn
index f720553..506100f 100644
--- a/library/MGCP_Templates.ttcn
+++ b/library/MGCP_Templates.ttcn
@@ -286,6 +286,22 @@
 		}
 	}
 
+	function f_mgcp_contains_par(MgcpMessage msg, MgcpInfoCode code) return boolean {
+		var MgcpParameterList pars;
+		if (ischosen(msg.command)) {
+			pars := msg.command.params;
+		} else {
+			pars := msg.response.params;
+		}
+		for (var integer i := 0; i < lengthof(pars); i := i + 1) {
+			var MgcpParameter par := pars[i];
+			if (par.code == code) {
+				return true;
+			}
+		}
+		return false;
+	}
+
 	function f_mgcp_extract_par(MgcpMessage msg, MgcpInfoCode code) return charstring {
 		var MgcpParameterList pars;
 		if (ischosen(msg.command)) {
@@ -317,6 +333,13 @@
 		return f_mgcp_extract_par(msg, code);
 	}
 
+	function f_MgcpCmd_contains_par(MgcpCommand cmd, MgcpInfoCode code) return boolean {
+		var MgcpMessage msg := {
+			command := cmd
+		}
+		return f_mgcp_contains_par(msg, code);
+	}
+
 	function f_MgcpResp_extract_conn_id(MgcpResponse resp) return MgcpConnectionId {
 		return str2hex(f_MgcpResp_extract_par(resp, "I"));
 	}
diff --git a/library/MNCC_Types.ttcn b/library/MNCC_Types.ttcn
index a3714b1..f5028d2 100644
--- a/library/MNCC_Types.ttcn
+++ b/library/MNCC_Types.ttcn
@@ -1874,14 +1874,17 @@
 template MNCC_PDU ts_MNCC_RTP_CREATE(uint32_t call_id) := ts_MNCC_SIMPLE_RTP(MNCC_RTP_CREATE, call_id);
 
 /* MSC -> MNCC: RTP_CREATE.rsp; acknowledge creation of RTP (stating MSC side IP/Port) */
-template MNCC_PDU tr_MNCC_RTP_CREATE(template uint32_t call_id := ?) := {
+template MNCC_PDU tr_MNCC_RTP_CREATE(template uint32_t call_id := ?,
+				     template uint32_t ip := ?,
+				     template uint32_t rtp_port := ?,
+				     template uint32_t payload_type := ?) := {
 	msg_type := MNCC_RTP_CREATE,
 	u := {
 		rtp := {
 			callref := call_id,
-			ip := ?,
-			rtp_port := ?,
-			payload_type := ?,
+			ip := ip,
+			rtp_port := rtp_port,
+			payload_type := payload_type,
 			payload_msg_type := ?
 		}
 	}
diff --git a/msc/BSC_ConnectionHandler.ttcn b/msc/BSC_ConnectionHandler.ttcn
index 8e5c5f2..833c31f 100644
--- a/msc/BSC_ConnectionHandler.ttcn
+++ b/msc/BSC_ConnectionHandler.ttcn
@@ -479,12 +479,15 @@
 
 	f_establish_fully(EST_TYPE_PAG_RESP);
 
+	log("f_mt_call_complete 1");
+
 	/* MS <- MSC: Expect CC SETUP */
 	BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party)));
 
 	/* MS -> MSC: ALERTING */
 	BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_ALERTING(cpars.transaction_id)));
 	MNCC.receive(tr_MNCC_ALERT_ind(cpars.mncc_callref));
+	log("f_mt_call_complete 2");
 
 	/* Create MGCP expect */
 	f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
@@ -493,6 +496,7 @@
 
 	/* First MGCP CRCX (for BSS/RAN side) */
 	MGCP.receive(tr_CRCX) -> value mgcp_cmd {
+		log("f_mt_call_complete 3");
 		cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
 
 		/* When the endpoint contains a wildcard we keep the endpoint
@@ -521,6 +525,7 @@
 	interleave {
 	/* Second MGCP CRCX (this time for MSS/CN side) */
 	[] MGCP.receive(tr_CRCX(cpars.mgcp_ep)) -> value mgcp_cmd {
+		log("f_mt_call_complete 4");
 		var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_rtp_ip_mss, cpars.mgw_rtp_ip_mss,
 							hex2str(cpars.mgcp_call_id), "42",
 							cpars.mgw_rtp_port_mss,
@@ -529,25 +534,64 @@
 										cpars.rtp_sdp_format)),
 							  valueof(ts_SDP_ptime(20)) }));
 		MGCP.send(ts_CRCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp));
-		/* MSC acknowledges the MNCC_CREATE to the MNCC handler */
-		MNCC.receive(tr_MNCC_RTP_CREATE(cpars.mncc_callref));
+		}
+	
+	/* MSC acknowledges the MNCC_CREATE to the MNCC handler */
+	[] MNCC.receive(tr_MNCC_RTP_CREATE(cpars.mncc_callref)) {
+		log("f_mt_call_complete 5");
 		}
 
 	/* expect the MSC to trigger a BSSMAP ASSIGNMENT */
 	[] BSSAP.receive(tr_BSSMAP_AssignmentReq(omit, tla_ass)) {
 		var BSSMAP_IE_AoIP_TransportLayerAddress tla;
 		var BSSMAP_IE_SpeechCodec codec;
+		log("f_mt_call_complete 6");
 
 		tla := valueof(ts_BSSMAP_IE_AoIP_TLA4(f_inet_addr(cpars.bss_rtp_ip), cpars.bss_rtp_port));
 		codec := valueof(ts_BSSMAP_IE_SpeechCodec({ts_CodecFR}));
 
 		BSSAP.send(ts_BSSMAP_AssignmentComplete(omit, tla, codec));
+
+		BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CONNECT(cpars.transaction_id)));
 		}
+
+	[] MNCC.receive(tr_MNCC_SETUP_cnf(cpars.mncc_callref)) {
+		log("f_mt_call_complete 7");
+		MNCC.send(ts_MNCC_RTP_CONNECT(cpars.mncc_callref,
+					      /* ip 42.23.11.5 */ hex2int('42231105'H),
+					      /* port 423 */ 423,
+					      /* payload type 3 = GSM FR */ 3));
+		}
+
+	/* MDCX setting up the RAN side remote RTP address received from Assignment Complete */
+	[] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
+			log("f_mt_call_complete 8");
+			var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_rtp_ip_mss, cpars.mgw_rtp_ip_mss,
+								hex2str(cpars.mgcp_call_id), "42",
+								cpars.mgw_rtp_port_mss,
+								{ int2str(cpars.rtp_payload_type) },
+								{ valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
+											cpars.rtp_sdp_format)),
+								  valueof(ts_SDP_ptime(20)) }));
+			MGCP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp));
+		}
+
+	/* MDCX setting up the CN side remote RTP address received from MNCC CONNECT */
+	[] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
+			log("f_mt_call_complete 9");
+			var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_rtp_ip_mss, cpars.mgw_rtp_ip_mss,
+								hex2str(cpars.mgcp_call_id), "42",
+								cpars.mgw_rtp_port_mss,
+								{ int2str(cpars.rtp_payload_type) },
+								{ valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
+											cpars.rtp_sdp_format)),
+								  valueof(ts_SDP_ptime(20)) }));
+			MGCP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp));
+		}
+
 	}
 
-	/* MS -> MSC: ALERTING */
-	BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CONNECT(cpars.transaction_id)));
-	MNCC.receive(tr_MNCC_SETUP_cnf(cpars.mncc_callref));
+	log("f_mt_call_complete DONE");
 }
 
 function f_mt_call_establish(inout CallParameters cpars)
@@ -588,15 +632,20 @@
 	} else {
 		BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
 	}
+
+	var BSSMAP_IE_AoIP_TransportLayerAddress tla_ass :=
+		valueof(ts_BSSMAP_IE_AoIP_TLA4(f_inet_addr(cpars.mgw_rtp_ip_bss),cpars.mgw_rtp_port_bss));
+
 	interleave {
 	[] MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc {
+		log("f_mo_call_establish 1: rx MNCC SETUP ind");
 		cpars.mncc_callref := mncc.u.signal.callref;
-		/* Call Proceeding */
-		MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
-		BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
-		};
+		MNCC.send(ts_MNCC_RTP_CREATE(cpars.mncc_callref));
+		}
+
 	/* First MGCP CRCX (for BSS/RAN side) */
 	[] MGCP.receive(tr_CRCX) -> value mgcp_cmd {
+		log("f_mo_call_establish 2: rx 1st CRCX");
 		cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
 
 		/* When the endpoint contains a wildcard we keep the endpoint
@@ -619,13 +668,43 @@
 		f_mgcp_par_append(mgcp_resp.params, ts_MgcpParSpecEP(cpars.mgcp_ep));
 		MGCP.send(mgcp_resp);
 		}
-	}
 
-	var BSSMAP_IE_AoIP_TransportLayerAddress tla_ass :=
-		valueof(ts_BSSMAP_IE_AoIP_TLA4(f_inet_addr(cpars.mgw_rtp_ip_bss),cpars.mgw_rtp_port_bss));
-	interleave {
+	[] MNCC.receive(tr_MNCC_RTP_CREATE(cpars.mncc_callref)) {
+		log("f_mo_call_establish 3: rx RTP CREATE");
+		/* Call Proceeding */
+		MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
+		BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
+
+		/* Alerting */
+		MNCC.send(ts_MNCC_ALERT_req(cpars.mncc_callref));
+		};
+
+	/* expect AoIP IP/Port to match what we returned in CRCX_ACK above */
+	[] BSSAP.receive(tr_BSSMAP_AssignmentReq(omit, tla_ass)) {
+		log("f_mo_call_establish 4: rx Assignment Request");
+		var BSSMAP_IE_AoIP_TransportLayerAddress tla;
+		var BSSMAP_IE_SpeechCodec codec;
+		tla := valueof(ts_BSSMAP_IE_AoIP_TLA4(f_inet_addr(cpars.bss_rtp_ip), cpars.bss_rtp_port));
+		codec := valueof(ts_BSSMAP_IE_SpeechCodec({ts_CodecFR}));
+		BSSAP.send(ts_BSSMAP_AssignmentComplete(omit, tla, codec));
+		}
+
+	/* MDCX setting up the RAN side remote RTP address received from Assignment Complete */
+	[] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
+		log("f_mo_call_establish 5: rx MDCX for the RAN side");
+		var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_rtp_ip_mss, cpars.mgw_rtp_ip_mss,
+							hex2str(cpars.mgcp_call_id), "42",
+							cpars.mgw_rtp_port_mss,
+							{ int2str(cpars.rtp_payload_type) },
+							{ valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
+										cpars.rtp_sdp_format)),
+							  valueof(ts_SDP_ptime(20)) }));
+		MGCP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp));
+		}
+
 	/* Second MGCP CRCX (this time for MSS/CN side) */
 	[] MGCP.receive(tr_CRCX(cpars.mgcp_ep)) -> value mgcp_cmd {
+		log("f_mo_call_establish 6: rx 2nd CRCX, for CN side");
 		var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_rtp_ip_mss, cpars.mgw_rtp_ip_mss,
 							hex2str(cpars.mgcp_call_id), "42",
 							cpars.mgw_rtp_port_mss,
@@ -634,31 +713,50 @@
 										cpars.rtp_sdp_format)),
 							  valueof(ts_SDP_ptime(20)) }));
 		MGCP.send(ts_CRCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp));
-
-		/* Alerting */
-		MNCC.send(ts_MNCC_ALERT_req(cpars.mncc_callref));
 		}
 
 	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_ALERTING(cpars.transaction_id))) {
+		log("f_mo_call_establish 7: rx CC Alerting");
+		cpars.mncc_callref := mncc.u.signal.callref;
+		/* Call Proceeding */
+		MNCC.send(ts_MNCC_RTP_CONNECT(cpars.mncc_callref,
+					      /* ip 42.23.11.5 */ hex2int('42231105'H),
+					      /* port 423 */ 423,
+					      /* payload type 3 = GSM FR */ 3));
+		MNCC.send(ts_MNCC_SETUP_rsp(cpars.mncc_callref));
 		}
-	/* expect AoIP IP/Port to match what we returned in CRCX_ACK above */
-	[] BSSAP.receive(tr_BSSMAP_AssignmentReq(omit, tla_ass)) {
-		var BSSMAP_IE_AoIP_TransportLayerAddress tla;
-		var BSSMAP_IE_SpeechCodec codec;
-		tla := valueof(ts_BSSMAP_IE_AoIP_TLA4(f_inet_addr(cpars.bss_rtp_ip), cpars.bss_rtp_port));
-		codec := valueof(ts_BSSMAP_IE_SpeechCodec({ts_CodecFR}));
-		BSSAP.send(ts_BSSMAP_AssignmentComplete(omit, tla, codec));
+
+	[] MNCC.receive(tr_MNCC_SETUP_COMPL_ind(?)) -> value mncc {
+		log("f_mo_call_establish 8: rx MNCC SETUP COMPLETE ind");
+		}
+
+	/* second MDCX setting up the CN side remote RTP address and codec received from MNCC RTP CONNECT */
+	[] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
+		log("f_mo_call_establish 9: rx MDCX for CN side");
+		var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_rtp_ip_mss, cpars.mgw_rtp_ip_mss,
+							hex2str(cpars.mgcp_call_id), "42",
+							cpars.mgw_rtp_port_mss,
+							{ int2str(cpars.rtp_payload_type) },
+							{ valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
+										cpars.rtp_sdp_format)),
+							  valueof(ts_SDP_ptime(20)) }));
+		MGCP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp));
+		}
+
+	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CONNECT(cpars.transaction_id))) {
+		log("f_mo_call_establish 10: rx CC CONNECT");
+		BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CONNECT_ACK(cpars.transaction_id)));
 		}
 	}
 
-	/* Answer. MNCC_SETUP_RSP -> CONNECT to MS; CONNECT_ACK from MS */
-	MNCC.send(ts_MNCC_SETUP_rsp(cpars.mncc_callref));
-	BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CONNECT(cpars.transaction_id)));
-	BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CONNECT_ACK(cpars.transaction_id)));
-
+	log("f_mo_call_establish DONE");
 	setverdict(pass);
 }
 
+private altstep as_optional_mgcp_mdcx() runs on BSC_ConnHdlr {
+	[] MGCP.receive(tr_MDCX) {};
+}
+
 function f_call_hangup(inout CallParameters cpars, boolean release_by_ms, boolean is_csfb := false)
 runs on BSC_ConnHdlr {
 
@@ -666,6 +764,7 @@
 	var MNCC_PDU mncc;
 	var MgcpCommand mgcp_cmd;
 	var boolean respond_to_dlcx;
+	var boolean dlcx_contained_ci := false;
 	var template PDU_BSSAP t_clear := tr_BSSMAP_ClearCommand;
 
 	if (is_csfb) {
@@ -676,11 +775,13 @@
 	BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(cpars.transaction_id)));
 
 	if (release_by_ms) {
+		log("f_call_hangup 1a");
 		/* B-side (MS) Release of call */
 		BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_RELEASE(cpars.transaction_id, '1'B, '0000000'B)));
 		MNCC.receive(tr_MNCC_REL_ind(cpars.mncc_callref));
 		BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_REL_COMPL(cpars.transaction_id)));
 	} else {
+		log("f_call_hangup 1b");
 		/* A-side (PLMN) Release of call */
 		MNCC.send(ts_MNCC_REL_req(cpars.mncc_callref, valueof(ts_MNCC_cause(42))));
 		BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
@@ -689,21 +790,42 @@
 
 	respond_to_dlcx := not (isbound(cpars.mgw_drop_dlcx) and valueof(cpars.mgw_drop_dlcx));
 
+	var default mdcx := activate(as_optional_mgcp_mdcx());
+
 	/* clearing of radio channel */
 	interleave {
 	[] BSSAP.receive(t_clear) {
+		log("f_call_hangup 2");
 		BSSAP.send(ts_BSSMAP_ClearComplete);
 		BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
+		log("f_call_hangup 3");
 		}
 	[] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
-		if (respond_to_dlcx) {
-			/* TODO: For one or all connections on EP? */
-			MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
-			f_create_mgcp_delete_ep(cpars.mgcp_ep);
-		}
+			log("f_call_hangup 4");
+			if (respond_to_dlcx) {
+				MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
+			}
+			dlcx_contained_ci := f_MgcpCmd_contains_par(mgcp_cmd, "I");
 		}
 	}
 
+	/* Two DLCXes expected, one for RAN and one for CN side.
+	 * Unless the first DLCX did not contain a CI, in which case it was a wildcard DLCX for both. */
+	if (dlcx_contained_ci) {
+		MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
+				log("f_call_hangup 5");
+				if (respond_to_dlcx) {
+					MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
+				}
+			}
+		}
+	}
+
+	f_create_mgcp_delete_ep(cpars.mgcp_ep);
+
+	deactivate(mdcx);
+	log("f_call_hangup DONE");
+
 	setverdict(pass);
 }
 

-- 
To view, visit https://gerrit.osmocom.org/13616
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I162985045bb5e129977a3a797b656e30220990df
Gerrit-Change-Number: 13616
Gerrit-PatchSet: 1
Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190412/30c15a42/attachment.html>


More information about the gerrit-log mailing list