asterisk: Introduce test TC_ims_registration_423_interval_too_brief

Related: SYS#6983
Change-Id: I9e1fc9b79496956d27102d940dfa3897897733a7
diff --git a/asterisk/Asterisk_Tests.ttcn b/asterisk/Asterisk_Tests.ttcn
index 6982146..b7981eb 100644
--- a/asterisk/Asterisk_Tests.ttcn
+++ b/asterisk/Asterisk_Tests.ttcn
@@ -562,6 +562,60 @@
 }
 
 /* Test IMS re-registration based on Expires (TS 24.229 5.1.1.4.1, RFC 3261 10.3)*/
+private function f_TC_ims_registration_423_interval_too_brief(charstring id) runs on IMS_ConnHdlr {
+	f_create_sip_expect(valueof(ts_SipUrl_from_Addr_Union(g_pars.subscr.registrar_sip_record.addr)));
+
+	var template (present) PDU_SIP_Request exp_req :=
+		tr_SIP_REGISTER(g_pars.registrar_sip_req_uri,
+				?,
+				tr_From(),
+				tr_To(),
+				tr_Via_from(?),
+				expires := tr_Expires(int2str(g_pars.subscr.registrar_expires)));
+	SIP.receive(exp_req) -> value g_rx_sip_req;
+
+	/* Double it and expect UAC to use it. */
+	g_pars.subscr.registrar_expires := g_pars.subscr.registrar_expires * 2;
+
+	/* Tx 423 Interval Too Brief */
+	var template (value) PDU_SIP_Response tx_resp;
+	tx_resp := ts_SIP_Response_423_Interval_Too_Brief(
+				g_rx_sip_req.msgHeader.callId.callid,
+				g_rx_sip_req.msgHeader.fromField,
+				g_rx_sip_req.msgHeader.toField,
+				g_rx_sip_req.msgHeader.via,
+				g_rx_sip_req.msgHeader.cSeq.seqNumber,
+				minExpires := ts_MinExpires(int2str(g_pars.subscr.registrar_expires)),
+				server := g_pars.server_name,
+				userAgent := omit);
+	SIP.send(tx_resp);
+
+	g_pars.subscr.exp_uac_expires := g_pars.subscr.registrar_expires;
+	as_IMS_register();
+
+	as_IMS_unregister();
+	setverdict(pass);
+}
+testcase TC_ims_registration_423_interval_too_brief() runs on test_CT {
+	var IMS_ConnHdlrPars pars;
+	var IMS_ConnHdlr vc_conn;
+	f_init();
+	pars := f_init_IMS_ConnHdlrPars();
+	vc_conn := f_start_handler_IMS(refers(f_TC_ims_registration_423_interval_too_brief), pars);
+
+	f_AMI_IMS_register(pars);
+
+	/* Stay registered for one second */
+	f_sleep(1.0);
+
+	/* Trigger unregistration: */
+	f_AMI_IMS_unregister(pars);
+
+	vc_conn.done;
+	f_shutdown();
+}
+
+/* Test IMS re-registration based on Expires (TS 24.229 5.1.1.4.1, RFC 3261 10.3)*/
 private function f_TC_ims_reregistration(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();
@@ -780,6 +834,7 @@
 	execute( TC_ims_registration_timeout_resync_401Unauthorized() );
 	execute( TC_ims_registration_timeout_protected_100Trying() );
 	execute( TC_ims_registration_timeout_protected_200OK() );
+	execute( TC_ims_registration_423_interval_too_brief() );
 	execute( TC_ims_reregistration() );
 	execute( TC_ims_call_mo() );
 	execute( TC_ims_call_mo_noprecondition() );
diff --git a/asterisk/IMS_ConnectionHandler.ttcn b/asterisk/IMS_ConnectionHandler.ttcn
index ba2a2fd..674b281 100644
--- a/asterisk/IMS_ConnectionHandler.ttcn
+++ b/asterisk/IMS_ConnectionHandler.ttcn
@@ -94,6 +94,7 @@
 	SipAddr registrar_sip_record,
 	CallidString registrar_sip_call_id,
 	integer registrar_sip_seq_nr,
+	integer exp_uac_expires,
 	integer registrar_expires,
 	SipUrl local_sip_url_ext,
 	SipAddr local_sip_record,
@@ -215,6 +216,7 @@
 					   f_sip_str_quote(display_name)),
 	registrar_sip_call_id := hex2str(f_rnd_hexstring(15)) & "@" & domain,
 	registrar_sip_seq_nr := f_sip_rand_seq_nr(),
+	exp_uac_expires := c_def_expires,
 	registrar_expires := c_def_expires,
 	local_sip_url_ext := ts_SipUrl(ts_HostPort(domain, local_sip_port),
 				       ts_UserInfo(imsi)),
@@ -747,7 +749,7 @@
 				tr_From(),
 				tr_To(),
 				tr_Via_from(?),
-				expires := tr_Expires(int2str(c_def_expires)),
+				expires := tr_Expires(int2str(g_pars.subscr.exp_uac_expires)),
 				require := tr_Require(superset("sec-agree")),
 				security_client := tr_Security_client(superset(tr_Security_mechanism("ipsec-3gpp",
 												     superset(tr_Param("alg","hmac-sha-1-96"))))),
diff --git a/asterisk/expected-results.xml b/asterisk/expected-results.xml
index 65a495b..26c2fa4 100644
--- a/asterisk/expected-results.xml
+++ b/asterisk/expected-results.xml
@@ -12,6 +12,7 @@
   <testcase classname='Asterisk_Tests' name='TC_ims_registration_timeout_resync_401Unauthorized' time='MASKED'/>
   <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_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_noprecondition' time='MASKED'/>
diff --git a/library/SIP_Templates.ttcn b/library/SIP_Templates.ttcn
index ce5998b..26f7ea8 100644
--- a/library/SIP_Templates.ttcn
+++ b/library/SIP_Templates.ttcn
@@ -245,6 +245,12 @@
 	fromParams := fromParams
 }
 
+// [20.23]
+template (value) MinExpires ts_MinExpires(template (value) DeltaSec deltaSec := "800000") := {
+	fieldName := MIN_EXPIRES_E,
+	deltaSec := deltaSec
+}
+
 // [RFC3455 5.4] + 3GPP 24.229 V8.7.0
 template (present) Access_net_spec tr_Access_net_spec(template (present) charstring access_type := ?,
 						      template SemicolonParam_List access_info := *) := {
@@ -685,6 +691,7 @@
 		template (omit)Authorization authorization := omit,
 		template (omit) Allow allow := ts_Allow(c_SIP_defaultMethods),
 		template (omit) Expires expires := omit,
+		template (omit) MinExpires minExpires := omit,
 		template (omit) P_Associated_Uri p_associated_uri := omit,
 		template (omit) RAck rack := omit,
 		template (omit) Require require := omit,
@@ -712,6 +719,7 @@
 	},
 	expires := expires,
 	fromField := from_addr,
+	minExpires := minExpires,
 	p_associated_uri := p_associated_uri,
 	rack := rack,
 	require := require,
@@ -1152,6 +1160,34 @@
 	payload := omit
 }
 
+/* Tx 423 Interval Too Brief */
+template (value) PDU_SIP_Response
+ts_SIP_Response_423_Interval_Too_Brief(
+	template (value) CallidString call_id,
+	template (value) From from_addr,
+	template (value) To to_addr,
+	Via via,
+	integer seq_nr,
+	charstring method := "REGISTER",
+	template (omit) Allow allow := omit,
+	template (value) MinExpires minExpires := ts_MinExpires(),
+	template (omit) Server server := omit,
+	template (omit) Supported supported := omit,
+	template (omit) UserAgent userAgent := omit) := {
+	statusLine := ts_SIP_StatusLine(423, "Interval Too Brief"),
+	msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, method, seq_nr,
+				     via,
+				     content_length := f_ContentLength(omit),
+				     content_type := f_ContentTypeOrOmit(ts_CT_SDP, omit),
+				     allow := allow,
+				     minExpires := minExpires,
+				     server := server,
+				     supported := supported,
+				     userAgent := userAgent),
+	messageBody := omit,
+	payload := omit
+}
+
 template (present) PDU_SIP_Response
 tr_SIP_Response(template CallidString call_id,
 		template From from_addr,