pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/37310?usp=email )
Change subject: asterisk: Introduce test TC_ims_call_mo_session_timer ......................................................................
asterisk: Introduce test TC_ims_call_mo_session_timer
Related: SYS#6987 Change-Id: Ia87feb6499283a7b51644c391c94a2259415bca2 --- M asterisk/Asterisk_Tests.ttcn M asterisk/IMS_ConnectionHandler.ttcn M asterisk/SIP_ConnectionHandler.ttcn M asterisk/expected-results.xml 4 files changed, 155 insertions(+), 38 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/10/37310/1
diff --git a/asterisk/Asterisk_Tests.ttcn b/asterisk/Asterisk_Tests.ttcn index 73e8183..f6b6b3e 100644 --- a/asterisk/Asterisk_Tests.ttcn +++ b/asterisk/Asterisk_Tests.ttcn @@ -215,6 +215,7 @@ COORD.receive(COORD_CMD_HANGUP); f_SIP_do_call_hangup();
+ COORD.receive(COORD_CMD_UNREGISTER); f_SIP_unregister();
setverdict(pass); @@ -242,6 +243,8 @@ } as_SIP_exp_call_hangup(g_pars.cp.sip_seq_nr + 1);
+ COORD.send(COORD_CMD_CALL_FINISHED); + COORD.receive(COORD_CMD_UNREGISTER); f_SIP_unregister();
setverdict(pass); @@ -280,7 +283,10 @@ f_sleep(1.0);
COORD.send(COORD_CMD_HANGUP) to vc_conn[0]; + COORD.receive(COORD_CMD_CALL_FINISHED) from vc_conn[1];
+ COORD.send(COORD_CMD_UNREGISTER) to vc_conn[0]; + COORD.send(COORD_CMD_UNREGISTER) to vc_conn[1];
vc_conn[0].done; vc_conn[1].done; @@ -353,6 +359,12 @@
COORD.send(COORD_CMD_HANGUP) to vc_conn_list[vc_conn_mo_idx];
+ COORD.receive(COORD_CMD_CALL_FINISHED) from vc_conn_list[vc_conn_mt_idx]; + + for (var integer i := 0; i < num_conns; i := i + 1) { + COORD.send(COORD_CMD_UNREGISTER) to vc_conn_list[i]; + } + for (var integer i := 0; i < num_conns; i := i + 1) { vc_conn_list[i].done; } @@ -656,34 +668,8 @@ f_shutdown(); }
-/* 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))); - } - as_IMS_register(); - setverdict(pass); - as_IMS_mo_call_accept(); - setverdict(pass); - COORD.send(COORD_CMD_CALL_ESTABLISHED); - as_IMS_exp_call_hangup(g_pars.subscr.cp.sip_seq_nr + 1); - setverdict(pass); - as_IMS_unregister(); -} -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; - var IMS_ConnHdlr vc_conn_ims; - var AMI_Msg ami_msg; +private function f_ims_call_mo_configure(inout SIPConnHdlrPars sip_pars, inout IMS_ConnHdlrPars ims_pars) runs on test_CT { const charstring c_ext_msisdn := "90829"; - - f_init(); - - sip_pars := f_init_ConnHdlrPars(idx := 1); - ims_pars := f_init_IMS_ConnHdlrPars(); - sip_pars.cp.calling := sip_pars.registrar_sip_record; sip_pars.cp.called := valueof(ts_SipAddr(ts_HostPort(sip_pars.remote_sip_host), ts_UserInfo(c_ext_msisdn))); @@ -691,16 +677,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; - ims_pars.subscr.cp.mo.tx_coord_cmd_invite_trying := true; +}
- 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; - - f_AMI_IMS_register(ims_pars); +private function f_ims_call_mo_establish(inout SIPConnHdlr vc_conn_sip, inout IMS_ConnHdlr vc_conn_ims) runs on test_CT { + var AMI_Msg ami_msg;
COORD.send(COORD_CMD_START) to vc_conn_sip;
@@ -714,14 +694,84 @@
COORD.receive(COORD_CMD_CALL_ESTABLISHED) from vc_conn_sip; IMS_COORD.receive(COORD_CMD_CALL_ESTABLISHED) from vc_conn_ims; +} + +/* 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))); + } + as_IMS_register(); + setverdict(pass); + as_IMS_mo_call_accept(); + setverdict(pass); + COORD.send(COORD_CMD_CALL_ESTABLISHED); + if (g_pars.subscr.cp.mo.support_timer_session_expires > 0) { + timer Trefresh; + Trefresh.start(int2float(g_pars.subscr.cp.mo.support_timer_session_expires)); + alt { + [] as_IMS_exp_call_refresh(); + [] Trefresh.timeout { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str(g_name & ": Timeout waiting for Session Refresh")); + } + } + Trefresh.stop; + /* Sleep to make sure response arrives to the peer */ + f_sleep(1.0); + COORD.send(IMS_COORD_CMD_CALL_SESSION_REFRESH); + } + as_IMS_exp_call_hangup(g_pars.subscr.cp.sip_seq_nr + 1); + COORD.send(IMS_COORD_CMD_CALL_FINISHED); + setverdict(pass); + as_IMS_unregister(); +} + +private function f_TC_ims_call_mo(boolean use_precondition_ext, boolean use_session_timer) runs on test_CT { + var SIPConnHdlrPars sip_pars; + var IMS_ConnHdlrPars ims_pars; + var SIPConnHdlr vc_conn_sip; + var IMS_ConnHdlr vc_conn_ims; + + f_init(); + + sip_pars := f_init_ConnHdlrPars(idx := 1); + ims_pars := f_init_IMS_ConnHdlrPars(); + + f_ims_call_mo_configure(sip_pars, ims_pars); + ims_pars.subscr.cp.support_precondition_ext := use_precondition_ext; + ims_pars.subscr.cp.require_precondition_ext := use_precondition_ext; + ims_pars.subscr.cp.mo.tx_coord_cmd_invite_trying := true; + ims_pars.subscr.cp.mo.support_timer_enable := use_session_timer; + if (use_session_timer) { + sip_pars.t_guard := 120.0; + ims_pars.t_guard := 120.0; + ims_pars.subscr.cp.mo.support_timer_exp_min_se := 90; + ims_pars.subscr.cp.mo.support_timer_session_expires := 90; + + } + + 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; + + f_AMI_IMS_register(ims_pars); + + f_ims_call_mo_establish(vc_conn_sip, vc_conn_ims);
/* Call on-going */ + if (use_session_timer) { + IMS_COORD.receive(IMS_COORD_CMD_CALL_SESSION_REFRESH); + } f_sleep(1.0);
COORD.send(COORD_CMD_HANGUP) to vc_conn_sip; + IMS_COORD.receive(IMS_COORD_CMD_CALL_FINISHED) from vc_conn_ims;
/* Trigger unregistration: */ f_sleep(1.0); + COORD.send(COORD_CMD_UNREGISTER) to vc_conn_sip; AMI_CLIENT.clear; f_AMI_IMS_unregister(ims_pars);
@@ -730,10 +780,13 @@ f_shutdown(); } testcase TC_ims_call_mo() runs on test_CT { - f_TC_ims_call_mo(true); + f_TC_ims_call_mo(true, false); +} +testcase TC_ims_call_mo_session_timer() runs on test_CT { + f_TC_ims_call_mo(true, true); } testcase TC_ims_call_mo_noprecondition() runs on test_CT { - f_TC_ims_call_mo(false); + f_TC_ims_call_mo(false, false); }
/* Test SIP registration of local clients */ @@ -839,6 +892,7 @@ execute( TC_ims_registration_423_interval_too_brief() ); execute( TC_ims_reregistration() ); execute( TC_ims_call_mo() ); + execute( TC_ims_call_mo_session_timer() ); 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 bb5223a..881240b 100644 --- a/asterisk/IMS_ConnectionHandler.ttcn +++ b/asterisk/IMS_ConnectionHandler.ttcn @@ -47,8 +47,10 @@ const charstring IMS_COORD_CMD_START := "IMS_COORD_CMD_START"; const charstring IMS_COORD_CMD_CALL_ESTABLISHED := "IMS_COORD_CMD_CALL_ESTABLISHED"; const charstring IMS_COORD_CMD_HANGUP := "IMS_COORD_CMD_HANGUP"; +const charstring IMS_COORD_CMD_CALL_FINISHED := "IMS_COORD_CMD_CALL_FINISHED"; const charstring IMS_COORD_CMD_CALL_TRYING := "IMS_COORD_CMD_CALL_TRYING"; const charstring IMS_COORD_CMD_CALL_SESSION_PROGRESS := "IMS_COORD_CMD_CALL_SESSION_PROGRESS"; +const charstring IMS_COORD_CMD_CALL_SESSION_REFRESH := "IMS_COORD_CMD_CALL_SESSION_REFRESH";
type component IMS_ConnHdlr extends SIP_ConnHdlr { var charstring g_name; @@ -1678,4 +1680,52 @@ [fail_others] as_SIP_fail_req(sip_expect_str); }
+private function f_IMS_answer_call_refresh(PDU_SIP_Request req) runs on IMS_ConnHdlr { + var template (value) PDU_SIP_Response tx_resp; + /* Tx 200 OK response*/ + tx_resp := ts_SIP_Response(g_pars.subscr.cp.sip_call_id, + g_pars.subscr.cp.from_addr, + g_pars.subscr.cp.to_addr, + g_rx_sip_req.msgHeader.cSeq.method, 200, + g_rx_sip_req.msgHeader.cSeq.seqNumber, + "OK", + g_rx_sip_req.msgHeader.via, + session_expires := ts_Session_expires(int2str(g_pars.subscr.cp.mo.support_timer_session_expires), + {ts_Param("refresher", "uac")}), + supported := ts_Supported({"timer"}), + body := omit); + SIP.send(tx_resp); +} +/* Session Timer, RFC 4028 */ +altstep as_IMS_exp_call_refresh() runs on IMS_ConnHdlr +{ + /* RFC4028 section 7.4. It can be either INVITE or UPDATE: */ + var template (present) PDU_SIP_Request exp_req_invite := + tr_SIP_INVITE(f_tr_SipUrl_opt_defport(ts_SipUrl_from_Addr_Union(g_pars.subscr.cp.called.addr)), + ?, + tr_From(tr_Addr_Union_from_val(g_pars.subscr.cp.calling.addr), *), + tr_To(tr_Addr_Union_from_val(g_pars.subscr.cp.called.addr), *), + tr_Via_from(f_tr_HostPort(g_pars.subscr.remote_sip_host, g_pars.subscr.ipsec_remote_port_s)), + ?, + supported := tr_Supported(superset("timer")), + body := *); + + var template (present) PDU_SIP_Request exp_req_update := + 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, + tr_Via_from(f_tr_HostPort(g_pars.subscr.remote_sip_host, g_pars.subscr.ipsec_remote_port_s)), + ?, + body := *); + + [] SIP.receive(exp_req_invite) -> value g_rx_sip_req { + f_IMS_answer_call_refresh(g_rx_sip_req); + g_pars.subscr.cp.sip_seq_nr := g_rx_sip_req.msgHeader.cSeq.seqNumber; + } + [] SIP.receive(exp_req_update) -> value g_rx_sip_req { + f_IMS_answer_call_refresh(g_rx_sip_req); + g_pars.subscr.cp.sip_seq_nr := g_rx_sip_req.msgHeader.cSeq.seqNumber; + } +} } diff --git a/asterisk/SIP_ConnectionHandler.ttcn b/asterisk/SIP_ConnectionHandler.ttcn index 5aa3773..3bc4f1d 100644 --- a/asterisk/SIP_ConnectionHandler.ttcn +++ b/asterisk/SIP_ConnectionHandler.ttcn @@ -34,6 +34,8 @@ const charstring COORD_CMD_CALL_ESTABLISHED := "COORD_CMD_CALL_ESTABLISHED"; const charstring COORD_CMD_CALL_CANCELLED := "COORD_CMD_CALL_CANCELLED"; const charstring COORD_CMD_HANGUP := "COORD_CMD_HANGUP"; +const charstring COORD_CMD_CALL_FINISHED := "COORD_CMD_CALL_FINISHED"; +const charstring COORD_CMD_UNREGISTER := "IMS_COORD_CMD_UNREGISTER";
type component SIPConnHdlr extends SIP_ConnHdlr { var charstring g_name; diff --git a/asterisk/expected-results.xml b/asterisk/expected-results.xml index 26c2fa4..179ee70 100644 --- a/asterisk/expected-results.xml +++ b/asterisk/expected-results.xml @@ -15,6 +15,7 @@ <testcase classname='Asterisk_Tests' name='TC_ims_registration_423_interval_too_brief' time='MASKED'/> <testcase classname='Asterisk_Tests' name='TC_ims_reregistration' time='MASKED'/> <testcase classname='Asterisk_Tests' name='TC_ims_call_mo' time='MASKED'/> + <testcase classname='Asterisk_Tests' name='TC_ims_call_mo_session_timer' 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'/>