lib/DIAMETER: Allow sending CEA with AuthAppId

The new message is to be used by Gy interface emulation, which according
to RFC4006 uses AppId 4 "Credit Control Application". The application
is apparently not 3GPP vendor specific.

Change-Id: I0e33673d65140aad34d2efcae3c7f49154ceb99f
diff --git a/ggsn_tests/GGSN_Tests.ttcn b/ggsn_tests/GGSN_Tests.ttcn
index 7a7ff97..203dcbf 100644
--- a/ggsn_tests/GGSN_Tests.ttcn
+++ b/ggsn_tests/GGSN_Tests.ttcn
@@ -210,6 +210,7 @@
 			local_sctp_port := PCRF_PORT,
 			origin_host := "pcrf.localdomain",
 			origin_realm := "localdomain",
+			auth_app_id := omit,
 			vendor_app_id := c_DIAMETER_3GPP_Gx_AID
 		};
 		vc_Gx := DIAMETER_Emulation_CT.create(id);
diff --git a/library/DIAMETER_Emulation.ttcn b/library/DIAMETER_Emulation.ttcn
index e35a87a..73fc87c 100644
--- a/library/DIAMETER_Emulation.ttcn
+++ b/library/DIAMETER_Emulation.ttcn
@@ -111,7 +111,8 @@
 	PortNumber local_sctp_port,
 	charstring origin_host,
 	charstring origin_realm,
-	uint32_t vendor_app_id
+	uint32_t auth_app_id optional,
+	uint32_t vendor_app_id optional
 }
 
 function tr_DIAMETER_RecvFrom_R(template PDU_DIAMETER msg)
@@ -329,8 +330,8 @@
 		/* handle CER/CEA handshake */
 		[] DIAMETER.receive(tr_DIAMETER_RecvFrom_R(tr_DIAMETER_R(cmd_code := Capabilities_Exchange))) -> value mrf {
 			var template (value) PDU_DIAMETER resp;
-			resp := ts_DIA_CEA(mrf.msg.hop_by_hop_id, mrf.msg.end_to_end_id, p.origin_host,
-					   p.origin_realm, f_inet_addr(p.local_ip), p.vendor_app_id);
+			resp := f_ts_DIA_CEA(mrf.msg.hop_by_hop_id, mrf.msg.end_to_end_id, p.origin_host,
+					   p.origin_realm, f_inet_addr(p.local_ip), p.auth_app_id, p.vendor_app_id);
 			DIAMETER.send(t_DIAMETER_Send(g_diameter_conn_id, resp));
 			/* notify our user that the CER->CEA exchange has happened */
 			DIAMETER_UNIT.send(DiameterCapabilityExchgInd:{rx:=mrf.msg, tx:=valueof(resp)});
diff --git a/library/DIAMETER_Templates.ttcn b/library/DIAMETER_Templates.ttcn
index b56363f..944dfd7 100644
--- a/library/DIAMETER_Templates.ttcn
+++ b/library/DIAMETER_Templates.ttcn
@@ -864,9 +864,31 @@
 
 /* 5.3.2 Capabilities Exchange Answer */
 template (value) PDU_DIAMETER
-ts_DIA_CEA(template (value) UINT32 hbh_id, template (value) UINT32 ete_id,
-	   template (value) charstring origin_host, template (value) charstring origin_realm,
-	   template (value) octetstring host_ip, uint32_t vendor_app_id)
+ts_DIA_CEA_AUTH_APP_ID(template (value) UINT32 hbh_id, template (value) UINT32 ete_id,
+		       template (value) charstring origin_host,
+		       template (value) charstring origin_realm,
+		       template (value) octetstring host_ip, uint32_t auth_app_id)
+:= ts_DIAMETER(flags:='00000000'B, cmd_code:=Capabilities_Exchange, hbh_id:=hbh_id, ete_id:=ete_id,
+	avps := {
+		ts_AVP_ResultCode(DIAMETER_SUCCESS),
+		ts_AVP_OriginHost(origin_host),
+		ts_AVP_OriginRealm(origin_realm),
+		ts_AVP_HostIpAddr(host_ip),
+		ts_AVP_VendorId(vendor_id_3GPP),
+		ts_AVP_ProductName("TTCN-3 Testsuite"),
+		ts_AVP_OriginStateId('00000001'O),
+		ts_AVP_SuppVendorIdRaw(5535), /* 3GPP2 */
+		ts_AVP_SuppVendorId(vendor_id_3GPP),
+		ts_AVP_SuppVendorIdRaw(13019), /* ETSI */
+		ts_AVP_AuthAppId('FFFFFFFF'O),
+		ts_AVP_AuthAppId(int2oct(auth_app_id, 4)),
+		ts_AVP_InbSecId('00000000'O)
+	});
+template (value) PDU_DIAMETER
+ts_DIA_CEA_VENDOR_APP_ID(template (value) UINT32 hbh_id, template (value) UINT32 ete_id,
+			 template (value) charstring origin_host,
+			 template (value) charstring origin_realm,
+			 template (value) octetstring host_ip, uint32_t vendor_app_id)
 := ts_DIAMETER(flags:='00000000'B, cmd_code:=Capabilities_Exchange, hbh_id:=hbh_id, ete_id:=ete_id,
 	avps := {
 		ts_AVP_ResultCode(DIAMETER_SUCCESS),
@@ -883,6 +905,21 @@
 		ts_AVP_InbSecId('00000000'O),
 		ts_AVP_VendorSpecAppId(vendor_id_3GPP, vendor_app_id)
 	});
+function f_ts_DIA_CEA(template (value) UINT32 hbh_id, template (value) UINT32 ete_id,
+		      template (value) charstring origin_host,
+		      template (value) charstring origin_realm,
+		      template (value) octetstring host_ip, template (omit) uint32_t auth_app_id,
+		      template (omit) uint32_t vendor_app_id)
+	   return template (value) PDU_DIAMETER
+{
+	var template (value) PDU_DIAMETER diam_pdu;
+	if (istemplatekind(vendor_app_id, "omit")) {
+		diam_pdu := ts_DIA_CEA_AUTH_APP_ID(hbh_id, ete_id, origin_host, origin_realm, host_ip, valueof(auth_app_id));
+	} else {
+		diam_pdu := ts_DIA_CEA_VENDOR_APP_ID(hbh_id, ete_id, origin_host, origin_realm, host_ip, valueof(vendor_app_id));
+	}
+	return diam_pdu;
+}
 
 
 template (value) PDU_DIAMETER
diff --git a/mme/MME_Tests.ttcn b/mme/MME_Tests.ttcn
index 3c35359..14965e6 100644
--- a/mme/MME_Tests.ttcn
+++ b/mme/MME_Tests.ttcn
@@ -223,6 +223,7 @@
 		local_sctp_port := mp_s6_local_port,
 		origin_host := "hss.localdomain",
 		origin_realm := "localdomain",
+		auth_app_id := omit,
 		vendor_app_id := c_DIAMETER_3GPP_S6_AID
 	};
 	vc_DIAMETER := DIAMETER_Emulation_CT.create(id);
diff --git a/pgw/PGW_Tests.ttcn b/pgw/PGW_Tests.ttcn
index 34090d2..d9f4979 100644
--- a/pgw/PGW_Tests.ttcn
+++ b/pgw/PGW_Tests.ttcn
@@ -126,6 +126,7 @@
 		local_sctp_port := mp_pcrf_local_port,
 		origin_host := "pcrf.localdomain",
 		origin_realm := "localdomain",
+		auth_app_id := omit,
 		vendor_app_id := c_DIAMETER_3GPP_Gx_AID
 	};
 	vc_DIAMETER := DIAMETER_Emulation_CT.create(id);