asterisk: test Precondition extension in IMS MT call
Related: SYS#6969
Change-Id: Ic96a6f99edbcf299fde36a2146a3ce252e09536a
diff --git a/asterisk/Asterisk_Tests.ttcn b/asterisk/Asterisk_Tests.ttcn
index 981d5f1..596848b 100644
--- a/asterisk/Asterisk_Tests.ttcn
+++ b/asterisk/Asterisk_Tests.ttcn
@@ -49,7 +49,7 @@
charstring mp_ami_user := "test_user";
charstring mp_ami_secret := "1234";
charstring mp_volte_ims_outbound_registration := "volte_ims";
- /* Current default by pjproject (timeout_timer_val) is set to 32s, and not changed by Asterisk */
+ /* Current default by pjproject (timeout_timer_val) is set to 32s, and not changed by Asterisk */
integer mp_volte_ims_outbound_register_timeout := 32;
}
@@ -633,7 +633,7 @@
}
/* Test SIP registration of local clients */
-private function f_TC_ims_call_mt(charstring id) runs on IMS_ConnHdlr {
+private function f_TC_ims_call_mt_IMS_ConnHdlr(charstring id) runs on IMS_ConnHdlr {
f_create_sip_expect(valueof(ts_SipUrl_from_Addr_Union(g_pars.subscr.registrar_sip_record.addr)));
as_IMS_register();
COORD.send(IMS_COORD_CMD_REGISTERED);
@@ -650,7 +650,7 @@
as_IMS_unregister();
}
-testcase TC_ims_call_mt() runs on test_CT {
+private function f_TC_ims_call_mt(boolean use_precondition_ext) runs on test_CT {
var SIPConnHdlrPars sip_pars;
var IMS_ConnHdlrPars ims_pars;
var SIPConnHdlr vc_conn_sip;
@@ -670,8 +670,10 @@
ts_UserInfo(c_ext_msisdn)));
ims_pars.subscr.cp.called := valueof(ts_SipAddr(ts_HostPort(ims_pars.realm),
ts_UserInfo(ims_pars.subscr.msisdn)));
+ ims_pars.subscr.cp.support_precondition_ext := use_precondition_ext;
+ ims_pars.subscr.cp.require_precondition_ext := use_precondition_ext;
- vc_conn_ims := f_start_handler_IMS(refers(f_TC_ims_call_mt), ims_pars);
+ vc_conn_ims := f_start_handler_IMS(refers(f_TC_ims_call_mt_IMS_ConnHdlr), ims_pars);
vc_conn_sip := f_start_handler(refers(f_TC_internal_call_mt), sip_pars);
COORD.receive(COORD_CMD_REGISTERED) from vc_conn_sip;
@@ -699,6 +701,12 @@
vc_conn_ims.done;
f_shutdown();
}
+testcase TC_ims_call_mt() runs on test_CT {
+ f_TC_ims_call_mt(true);
+}
+testcase TC_ims_call_mt_noprecondition() runs on test_CT {
+ f_TC_ims_call_mt(false);
+}
control {
execute( TC_internal_registration() );
@@ -716,6 +724,7 @@
execute( TC_ims_call_mo() );
execute( TC_ims_call_mo_noprecondition() );
execute( TC_ims_call_mt() );
+ execute( TC_ims_call_mt_noprecondition() );
}
}
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,
diff --git a/asterisk/expected-results.xml b/asterisk/expected-results.xml
index e9d2b82..31a03e5 100644
--- a/asterisk/expected-results.xml
+++ b/asterisk/expected-results.xml
@@ -15,4 +15,5 @@
<testcase classname='Asterisk_Tests' name='TC_ims_call_mo' time='MASKED'/>
<testcase classname='Asterisk_Tests' name='TC_ims_call_mo_noprecondition' time='MASKED'/>
<testcase classname='Asterisk_Tests' name='TC_ims_call_mt' time='MASKED'/>
+ <testcase classname='Asterisk_Tests' name='TC_ims_call_mt_noprecondition' time='MASKED'/>
</testsuite>