asterisk: test Precondition extension in IMS MT call

Related: SYS#6969
Change-Id: Ic96a6f99edbcf299fde36a2146a3ce252e09536a
diff --git a/asterisk/IMS_ConnectionHandler.ttcn b/asterisk/IMS_ConnectionHandler.ttcn
index 860b799..dd3223c 100644
--- a/asterisk/IMS_ConnectionHandler.ttcn
+++ b/asterisk/IMS_ConnectionHandler.ttcn
@@ -954,6 +954,7 @@
 	[fail_others] as_SIP_fail_req(sip_expect_str);
 }
 
+/* IMS Core starts a call towards the peer: 3GPP TS 24.229 5.1.3.1 */
 function f_IMS_mt_call_setup() runs on IMS_ConnHdlr
 {
 	var template (value) PDU_SIP_Request req;
@@ -961,6 +962,8 @@
 	var template (present) From from_addr_exp;
 	var template (present) To to_addr_exp;
 	var Via via;
+	var template (omit) Require require := omit;
+	var template (omit) Supported supported := omit;
 	var charstring tx_sdp := f_gen_sdp();
 	var default d_trying, d_ringing;
 	var charstring branch_value;
@@ -983,12 +986,19 @@
 					ts_ContactAddress(g_pars.subscr.cp.calling.addr, omit)
 				}));
 
+	if (g_pars.subscr.cp.support_precondition_ext) {
+		/* indicate the support for "reliable provisional response"
+		 * and "preconditions mechanism" */
+		supported := ts_Supported({ "100rel", "precondition" });
+	}
+
 	req := ts_SIP_INVITE(g_pars.subscr.cp.sip_call_id,
 			     g_pars.subscr.cp.from_addr,
 			     g_pars.subscr.cp.to_addr,
 			     via,
 			     calling_contact,
 			     g_pars.subscr.cp.sip_seq_nr,
+			     supported := supported,
 			     body := tx_sdp);
 
 	SIP.send(req);
@@ -1001,6 +1011,75 @@
 			g_pars.subscr.cp.sip_seq_nr, "INVITE");
 	d_trying := activate(as_SIP_ignore_resp(exp));
 
+	if (g_pars.subscr.cp.require_precondition_ext) {
+		/* Rx 183 Session Progress */
+		exp := tr_SIP_Response_SessionProgress(
+				g_pars.subscr.cp.sip_call_id,
+				from_addr_exp,
+				to_addr_exp,
+				f_tr_Via_response(via),
+				g_pars.subscr.cp.sip_seq_nr, "INVITE",
+				require := tr_Require(superset("100rel", "precondition")),
+				rseq := tr_RSeq(?));
+		alt {
+		[] SIP.receive(exp) -> value g_rx_sip_resp;
+		[] SIP.receive(tr_SIP_Response_Ringing(?, ?, ?)) -> value g_rx_sip_resp {
+			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
+						log2str(g_name & ": Expected 183 Session Progress instead of 180 Ringing: ",
+							g_rx_sip_resp));
+			}
+		}
+
+		/* Tx PRACK */
+		req := ts_SIP_PRACK(g_pars.subscr.cp.to_addr.addressField.nameAddr.addrSpec,
+				    g_pars.subscr.cp.sip_call_id,
+				    g_pars.subscr.cp.from_addr,
+				    g_pars.subscr.cp.to_addr,
+				    via,
+				    g_rx_sip_resp.msgHeader.cSeq.seqNumber + 1,
+				    rack := ts_RAck(g_rx_sip_resp.msgHeader.rseq.response_num,
+						    g_rx_sip_resp.msgHeader.cSeq.seqNumber,
+						    "INVITE"),
+				    body := omit);
+		SIP.send(req);
+
+		/* Rx 200 OK (PRACK) */
+		exp := tr_SIP_Response(g_pars.subscr.cp.sip_call_id,
+				       from_addr_exp,
+				       to_addr_exp,
+				       f_tr_Via_response(via),
+				       omit,
+				       "PRACK", 200,
+				       g_rx_sip_resp.msgHeader.cSeq.seqNumber + 1, "OK",
+				       body := omit);
+		as_SIP_expect_resp(exp, fail_others := false);
+
+		/* Tx UPDATE */
+		req := ts_SIP_UPDATE(g_pars.subscr.cp.to_addr.addressField.nameAddr.addrSpec,
+				     g_pars.subscr.cp.sip_call_id,
+				     g_pars.subscr.cp.from_addr,
+				     g_pars.subscr.cp.to_addr,
+				     via,
+				     g_rx_sip_resp.msgHeader.cSeq.seqNumber + 1,
+				     contact := calling_contact,
+				     require := ts_Require({"sec-agree", "precondition"}),
+				     body := tx_sdp);
+		SIP.send(req);
+
+		/* Rx 200 OK (UPDATE) */
+		exp := tr_SIP_Response(g_pars.subscr.cp.sip_call_id,
+				       from_addr_exp,
+				       to_addr_exp,
+				       f_tr_Via_response(via),
+				       omit,
+				       "UPDATE", 200,
+				       g_rx_sip_resp.msgHeader.cSeq.seqNumber + 1, "OK",
+				       body := ?);
+		as_SIP_expect_resp(exp, fail_others := false);
+
+		g_pars.subscr.cp.sip_seq_nr := g_rx_sip_resp.msgHeader.cSeq.seqNumber + 1;
+	}
+
 	/* Conditionally match and accept 180 Ringing */
 	exp := tr_SIP_Response_Ringing(g_pars.subscr.cp.sip_call_id,
 			from_addr_exp,