asterisk: test Precondition extension in IMS MO call
Related: SYS#6969
Change-Id: I1e26f3bb9e54be5b5e15a003b2000ae3e88b9027
diff --git a/asterisk/Asterisk_Tests.ttcn b/asterisk/Asterisk_Tests.ttcn
index 05b1638..981d5f1 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) 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;
}
@@ -561,8 +561,8 @@
true, false);
}
-/* Test SIP registration of local clients */
-private function f_TC_ims_call_mo(charstring id) runs on IMS_ConnHdlr {
+/* Test IMS MO call emulating an MT which doesn't support precondition */
+private function f_TC_ims_call_mo_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)));
if (ispresent(g_pars.subscr.cp.called)) {
f_create_sip_expect(valueof(ts_SipUrl_from_Addr_Union(g_pars.subscr.cp.called.addr)));
@@ -576,7 +576,7 @@
setverdict(pass);
as_IMS_unregister();
}
-testcase TC_ims_call_mo() runs on test_CT {
+private function f_TC_ims_call_mo(boolean use_precondition_ext) runs on test_CT {
var SIPConnHdlrPars sip_pars;
var IMS_ConnHdlrPars ims_pars;
var SIPConnHdlr vc_conn_sip;
@@ -595,8 +595,10 @@
ts_UserInfo(ims_pars.subscr.msisdn)));
ims_pars.subscr.cp.called := valueof(ts_SipAddr(ts_HostPort(ims_pars.realm),
ts_UserInfo(c_ext_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_mo), ims_pars);
+ vc_conn_ims := f_start_handler_IMS(refers(f_TC_ims_call_mo_IMS_ConnHdlr), ims_pars);
vc_conn_sip := f_start_handler(refers(f_TC_internal_call_mo), sip_pars);
COORD.receive(COORD_CMD_REGISTERED) from vc_conn_sip;
@@ -623,6 +625,12 @@
vc_conn_ims.done;
f_shutdown();
}
+testcase TC_ims_call_mo() runs on test_CT {
+ f_TC_ims_call_mo(true);
+}
+testcase TC_ims_call_mo_noprecondition() runs on test_CT {
+ f_TC_ims_call_mo(false);
+}
/* Test SIP registration of local clients */
private function f_TC_ims_call_mt(charstring id) runs on IMS_ConnHdlr {
@@ -706,6 +714,7 @@
execute( TC_ims_registration_timeout_protected_100Trying() );
execute( TC_ims_registration_timeout_protected_200OK() );
execute( TC_ims_call_mo() );
+ execute( TC_ims_call_mo_noprecondition() );
execute( TC_ims_call_mt() );
}
diff --git a/asterisk/IMS_ConnectionHandler.ttcn b/asterisk/IMS_ConnectionHandler.ttcn
index 4f3cbb7..860b799 100644
--- a/asterisk/IMS_ConnectionHandler.ttcn
+++ b/asterisk/IMS_ConnectionHandler.ttcn
@@ -138,6 +138,8 @@
charstring local_rtp_addr,
uint16_t local_rtp_port,
+ boolean support_precondition_ext,
+ boolean require_precondition_ext,
SDP_Message peer_sdp optional,
IMS_CallParsMT mt
}
@@ -155,6 +157,8 @@
sip_body := omit,
local_rtp_addr := local_rtp_addr,
local_rtp_port := local_rtp_port,
+ support_precondition_ext := true,
+ require_precondition_ext := false,
peer_sdp := omit,
mt := t_IMS_CallParsMT
}
@@ -1104,24 +1108,106 @@
var template (value) PDU_SIP_Response tx_resp;
var Via via;
var charstring tx_sdp;
+ var boolean peer_support_precondition := match(g_rx_sip_req.msgHeader.supported.optionsTags,
+ superset("100rel", "precondition"));
/* Obtain params: */
f_ConnHdlr_parse_initial_SIP_INVITE(g_rx_sip_req);
via := g_rx_sip_req.msgHeader.via;
f_ims_validate_register_P_Access_Network_info(g_rx_sip_req, exp_present := true);
+ if (g_pars.subscr.cp.require_precondition_ext and not peer_support_precondition) {
+ Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
+ log2str(g_name & ": Missing '100rel,precondition' in INVITE Supported header: ",
+ g_rx_sip_req.msgHeader.supported));
+ }
-
- /* Tx 180 Ringing */
- tx_resp := ts_SIP_Response_Ringing(g_pars.subscr.cp.sip_call_id,
+ /* Tx 100 Tyring */
+ tx_resp := ts_SIP_Response_Trying(g_pars.subscr.cp.sip_call_id,
g_pars.subscr.cp.from_addr,
g_pars.subscr.cp.to_addr,
via,
- g_pars.subscr.cp.sip_seq_nr);
+ g_pars.subscr.cp.sip_seq_nr,
+ "INVITE",
+ allow := omit,
+ server := g_pars.server_name,
+ userAgent := omit);
SIP.send(tx_resp);
- /* Tx 200 OK */
tx_sdp := f_gen_sdp();
+
+ /* Use precondition ? */
+ if (g_pars.subscr.cp.require_precondition_ext or
+ (g_pars.subscr.cp.support_precondition_ext and peer_support_precondition)) {
+ /* Tx 183 Session Progress */
+ /* TODO: add a=curr:qos, a=des:qos and a=conf:qos fields to SDP */
+ tx_resp := ts_SIP_Response_SessionProgress(g_pars.subscr.cp.sip_call_id,
+ g_pars.subscr.cp.from_addr,
+ g_pars.subscr.cp.to_addr,
+ via,
+ g_pars.subscr.cp.sip_seq_nr,
+ rseq := ts_RSeq(1),
+ body := tx_sdp);
+ SIP.send(tx_resp);
+
+ /* Rx PRACK */
+ exp_req := tr_SIP_PRACK(f_tr_SipUrl_opt_defport(ts_SipUrl_from_Addr_Union(g_pars.subscr.cp.called.addr)),
+ g_pars.subscr.cp.sip_call_id,
+ g_pars.subscr.cp.from_addr,
+ g_pars.subscr.cp.to_addr,
+ f_tr_Via_response(via),
+ g_pars.subscr.cp.sip_seq_nr + 1,
+ rack := tr_RAck(1, g_pars.subscr.cp.sip_seq_nr, "INVITE"),
+ body := omit);
+ as_SIP_expect_req(exp_req);
+
+ /* Tx 200 OK (PRACK) */
+ tx_resp := ts_SIP_Response(g_pars.subscr.cp.sip_call_id,
+ g_pars.subscr.cp.from_addr,
+ g_pars.subscr.cp.to_addr,
+ "PRACK", 200,
+ g_pars.subscr.cp.sip_seq_nr,
+ "OK",
+ via,
+ body := omit);
+ SIP.send(tx_resp);
+
+ /* Rx UPDATE */
+ exp_req := tr_SIP_UPDATE(f_tr_SipUrl_opt_defport(ts_SipUrl_from_Addr_Union(g_pars.subscr.cp.called.addr)),
+ g_pars.subscr.cp.sip_call_id,
+ g_pars.subscr.cp.from_addr,
+ g_pars.subscr.cp.to_addr,
+ f_tr_Via_response(via),
+ g_pars.subscr.cp.sip_seq_nr + 1,
+ require := tr_Require(superset("precondition")),
+ body := ?);
+ as_SIP_expect_req(exp_req);
+
+ /* Tx 200 OK (UPDATE) */
+ /* TODO: add a=curr:qos, a=des:qos and a=conf:qos fields to SDP */
+ tx_resp := ts_SIP_Response(g_pars.subscr.cp.sip_call_id,
+ g_pars.subscr.cp.from_addr,
+ g_pars.subscr.cp.to_addr,
+ "UPDATE", 200,
+ g_pars.subscr.cp.sip_seq_nr,
+ "OK",
+ via,
+ body := tx_sdp);
+ SIP.send(tx_resp);
+
+ g_pars.subscr.cp.sip_seq_nr := g_pars.subscr.cp.sip_seq_nr + 1;
+ }
+
+ /* Tx 180 Ringing */
+ tx_resp := ts_SIP_Response_Ringing(g_pars.subscr.cp.sip_call_id,
+ g_pars.subscr.cp.from_addr,
+ g_pars.subscr.cp.to_addr,
+ via,
+ g_pars.subscr.cp.sip_seq_nr);
+ SIP.send(tx_resp);
+
+
+ /* Tx 200 OK */
tx_resp := ts_SIP_Response(g_pars.subscr.cp.sip_call_id,
g_pars.subscr.cp.from_addr,
g_pars.subscr.cp.to_addr,
diff --git a/asterisk/expected-results.xml b/asterisk/expected-results.xml
index 6b5def5..e9d2b82 100644
--- a/asterisk/expected-results.xml
+++ b/asterisk/expected-results.xml
@@ -13,5 +13,6 @@
<testcase classname='Asterisk_Tests' name='TC_ims_registration_timeout_protected_100Trying' time='MASKED'/>
<testcase classname='Asterisk_Tests' name='TC_ims_registration_timeout_protected_200OK' time='MASKED'/>
<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'/>
</testsuite>