pespin has submitted this change. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/37249?usp=email )
Change subject: asterisk: test Precondition extension in IMS MT call ......................................................................
asterisk: test Precondition extension in IMS MT call
Related: SYS#6969 Change-Id: Ic96a6f99edbcf299fde36a2146a3ce252e09536a --- M asterisk/Asterisk_Tests.ttcn M asterisk/IMS_ConnectionHandler.ttcn M asterisk/expected-results.xml M library/SIP_Templates.ttcn M sip/SIP_Tests.ttcn 5 files changed, 169 insertions(+), 6 deletions(-)
Approvals: Jenkins Builder: Verified pespin: Looks good to me, approved
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> diff --git a/library/SIP_Templates.ttcn b/library/SIP_Templates.ttcn index cfe21eb..d0210d1 100644 --- a/library/SIP_Templates.ttcn +++ b/library/SIP_Templates.ttcn @@ -736,6 +736,7 @@ template P_Associated_Uri p_associated_uri := *, template RAck rack := *, template Require require := *, + template RSeq rseq := *, template Security_client security_client := *, template Security_server security_server := *, template Server server := *, @@ -762,6 +763,7 @@ p_associated_uri := p_associated_uri, rack := rack, require := require, + rseq := rseq, security_client := security_client, security_server := security_server, server := server, @@ -833,13 +835,15 @@ template (value) Via via, template (value) Contact contact, integer seq_nr, + template (omit) Supported supported := omit, template (omit) charstring body := omit) := { requestLine := ts_SIP_ReqLine(INVITE_E, to_addr.addressField.nameAddr.addrSpec), msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, contact, "INVITE", seq_nr, via, content_length := f_ContentLength(body), - content_type := f_ContentTypeOrOmit(ts_CT_SDP, body)), + content_type := f_ContentTypeOrOmit(ts_CT_SDP, body), + supported := supported), messageBody := body, payload := omit } @@ -939,6 +943,25 @@ payload := omit }
+template (value) PDU_SIP_Request +ts_SIP_PRACK(template (value) SipUrl uri, + template (value) CallidString call_id, + template (value) From from_addr, + template (value) To to_addr, + template (value) Via via, + integer seq_nr, + template (value) RAck rack, + template (omit) charstring body := omit) := { + requestLine := ts_SIP_ReqLine(PRACK_E, uri), + msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, + "PRACK", seq_nr, + via, + content_length := f_ContentLength(body), + content_type := f_ContentTypeOrOmit(ts_CT_SDP, body), + rack := rack), + messageBody := body, + payload := omit +} template (present) PDU_SIP_Request tr_SIP_PRACK(template (present) SipUrl uri, template CallidString call_id, @@ -957,6 +980,24 @@ payload := omit }
+template (value) PDU_SIP_Request +ts_SIP_UPDATE(template (value) SipUrl uri, + template (value) CallidString call_id, + template (value) From from_addr, + template (value) To to_addr, + template (value) Via via, + integer seq_nr, + template (omit) Contact contact, + template (value) Require require := ts_Require({"sec-agree", "precondition"}), + template (value) charstring body) := { + requestLine := ts_SIP_ReqLine(UPDATE_E, uri), + msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, contact, + "UPDATE", seq_nr, + via, + require := require), + messageBody := body, + payload := omit +} template (present) PDU_SIP_Request tr_SIP_UPDATE(template (present) SipUrl uri, template CallidString call_id, @@ -1187,6 +1228,28 @@ payload := omit }
+/* 183 Session Progress */ +template (present) PDU_SIP_Response +tr_SIP_Response_SessionProgress( + template (present) CallidString call_id, + template (present) From from_addr, + template (present) To to_addr, + template (present) Via via, + template (present) integer seq_nr := ?, + template (present) charstring method := "INVITE", + template Require require := *, + template RSeq rseq := *, + template (omit) charstring body := omit) := { + statusLine := tr_SIP_StatusLine(183, "Session Progress"), + msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, *, + via, + method, seq_nr, + require := require, + rseq := rseq), + messageBody := body, + payload := omit +} + /**************** * FUNCTIONS: ****************/ diff --git a/sip/SIP_Tests.ttcn b/sip/SIP_Tests.ttcn index 9c376f3..10f8b4d 100644 --- a/sip/SIP_Tests.ttcn +++ b/sip/SIP_Tests.ttcn @@ -273,7 +273,8 @@ SIP.send(ts_SIP_INVITE(cp.comp.sip_call_id, from_addr, to_addr, via, ts_Contact_SipAddr(cp.comp.sip_url_ext), - cp.comp.sip_seq_nr, cp.comp.sip_body)); + cp.comp.sip_seq_nr, + body := cp.comp.sip_body)); if (cp.mncc_with_sdp) { /* We just sent SDP via SIP, now expect the same SDP in MNCC to the MSC */ expect_sdp_to_msc := cp.comp.sip_body;