asterisk: IMS: validate audio tag present in INVITE Contact header

Related: SYS#6984
Change-Id: I36011f36f0dd3f9ddafd658d003373bd63d1ae1b
diff --git a/asterisk/IMS_ConnectionHandler.ttcn b/asterisk/IMS_ConnectionHandler.ttcn
index d08dad4..b9a9852 100644
--- a/asterisk/IMS_ConnectionHandler.ttcn
+++ b/asterisk/IMS_ConnectionHandler.ttcn
@@ -338,7 +338,7 @@
 	f_sip_digest_validate_Authorization_AKAv1MD5(authorization, method, g_pars.subscr.auth.res);
 }
 
-
+/* GSMA IR-92 2.2.1 SIP Registration Procedure */
 private function f_ims_validate_register_contact(Contact rx_contact) runs on IMS_ConnHdlr
 {
 	/* IMS contact shows up like this:
@@ -435,6 +435,34 @@
 	}
 }
 
+/* GSMA IR.92 2.2.4 Call Establishment and Termination */
+private function f_ims_validate_INVITE_Contact(Contact rx_contact) runs on IMS_ConnHdlr
+{
+	/* INVITE Contact header shows up like this:
+	* Contact: <sip:e05d8e82-8565-47b5-aca5-5f6b9164b074@192.168.101.2:44823>;+g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel";audio;+g.3gpp.mid-call;+g.3gpp.srvcc-alerting;+g.3gpp.ps2cs-srvcc-orig-pre-alerting
+	*/
+	if (ischosen(rx_contact.contactBody.wildcard)) {
+		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
+			log2str(g_name & ": Received unexpected Contact wildcard := ", rx_contact));
+	}
+	var ContactAddress_List caddrs := rx_contact.contactBody.contactAddresses;
+	if (lengthof(caddrs) == 0) {
+		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
+				log2str(g_name & ": Received unexpected empty Contact Address list"));
+	}
+	for (var integer i := 0; i < lengthof(caddrs); i := i + 1) {
+		var ContactAddress caddr := caddrs[i];
+		/* "The UE must include the audio media feature tag, as defined in IETF RFC 3840,
+		 * in the Contact header field of the SIP INVITE request, and in the Contact header
+		 * field of the SIP response to the SIP INVITE request" */
+		if (not ispresent(caddr.contactParams)) {
+			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
+				log2str(g_name & ": Received unexpected empty Contact attributes (omit)"));
+		}
+		f_sip_param_match_value_or_fail(caddr.contactParams, "audio", omit);
+	}
+}
+
 private function f_ims_parse_security_client(Security_client security_client) runs on IMS_ConnHdlr
 {
 	var boolean found := false;
@@ -1187,7 +1215,7 @@
 			g_pars.subscr.cp.sip_seq_nr, "INVITE");
 	d_ringing := activate(as_SIP_ignore_resp(exp));
 
-	/* Wait for OK answer */
+	/* Wait for 200 OK (INVITE) answer */
 	exp := tr_SIP_Response(
 			g_pars.subscr.cp.sip_call_id,
 			from_addr_exp,
@@ -1202,6 +1230,9 @@
 	deactivate(d_trying);
 	deactivate(d_ringing);
 
+	/* Make sure "audio" tag set in Contact header */
+	f_ims_validate_INVITE_Contact(g_rx_sip_resp.msgHeader.contact);
+
 	/* Update To with the tags received from peer: */
 	g_pars.subscr.cp.to_addr := g_rx_sip_resp.msgHeader.toField;
 
@@ -1294,6 +1325,8 @@
 		via := g_rx_sip_req.msgHeader.via;
 
 		f_ims_validate_register_P_Access_Network_info(g_rx_sip_req, exp_present := true);
+		f_ims_validate_INVITE_Contact(g_rx_sip_req.msgHeader.contact);
+
 		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: ",