pgw: Improve checks around Gy messages

Change-Id: Ica3ca4cf72113d66e74dcff9f838e39cc5d63468
diff --git a/pgw/PGW_Tests.ttcn b/pgw/PGW_Tests.ttcn
index 44bf6f9..6df4ca7 100644
--- a/pgw/PGW_Tests.ttcn
+++ b/pgw/PGW_Tests.ttcn
@@ -1,5 +1,7 @@
 module PGW_Tests {
 
+import from TCCEncoding_Functions all;
+
 import from General_Types all;
 import from Osmocom_Types all;
 import from Native_Functions all;
@@ -33,6 +35,8 @@
 
 	charstring mp_ocs_local_ip := "127.0.0.9";
 	integer mp_ocs_local_port := 3869;
+
+	charstring mp_diam_realm := "localdomain";
 }
 
 /* main component, we typically have one per testcase */
@@ -112,7 +116,7 @@
 /* configuration data for a given Session */
 type record SessionPars {
 	hexstring	imsi,
-	octetstring	msisdn optional,
+	hexstring	msisdn optional,
 	// serving network
 	integer		rat_type,
 	// flags?
@@ -138,7 +142,7 @@
 t_SessionPars(hexstring imsi, charstring tundev, integer rat_type := 6, charstring apn := "internet",
 	      boolean selection_mode := false, BIT3 pdn_type := '001'B) := {
 	imsi := imsi,
-	msisdn := omit,
+	msisdn := '1234'H,
 	rat_type := rat_type,
 	apn := apn,
 	selection_mode := selection_mode,
@@ -176,8 +180,8 @@
 		remote_sctp_port := -1,
 		local_ip := mp_pcrf_local_ip,
 		local_sctp_port := mp_pcrf_local_port,
-		origin_host := "pcrf.localdomain",
-		origin_realm := "localdomain",
+		origin_host := "pcrf." & mp_diam_realm,
+		origin_realm := mp_diam_realm,
 		auth_app_id := omit,
 		vendor_app_id := c_DIAMETER_3GPP_Gx_AID
 	};
@@ -193,8 +197,8 @@
 		remote_sctp_port := -1,
 		local_ip := mp_ocs_local_ip,
 		local_sctp_port := mp_ocs_local_port,
-		origin_host := "ocs.localdomain",
-		origin_realm := "localdomain",
+		origin_host := "ocs." & mp_diam_realm,
+		origin_realm := mp_diam_realm,
 		auth_app_id := c_DIAMETER_CREDIT_CONTROL_AID,
 		vendor_app_id := omit
 	};
@@ -296,10 +300,6 @@
 	return f_concat_pad(15, '26242'H, suffix);
 }
 
-function f_gen_msisdn(integer suffix) return hexstring {
-	return f_concat_pad(12, '49123'H, suffix);
-}
-
 private altstep as_DIA_Gx_CCR(DCC_NONE_CC_Request_Type req_type) runs on PGW_Session_CT {
 	var PDU_DIAMETER rx_dia;
 	[] Gx.receive(tr_DIA_Gx_CCR(req_type := req_type)) -> value rx_dia {
@@ -322,9 +322,174 @@
 	}
 }
 
+function f_tr_DIA_Gy_CCR(DCC_NONE_CC_Request_Type req_type)
+runs on PGW_Session_CT return template (present) PDU_DIAMETER
+{
+	var template (present) PDU_DIAMETER tpl;
+	var charstring smf_origin_host := "smf." & mp_diam_realm;
+	var template (present) octetstring imsi := ?;
+	var template (present) octetstring msisdn := ?;
+	var template (present) octetstring rat_type := ?;
+	var template (present) OCT4 charging_char := ?;
+	var template (present) OCT1 nsapi := ?;
+	imsi := char2oct(f_dec_TBCD(imsi_hex2oct(g_pars.imsi)));
+	//msisdn := char2oct(f_dec_TBCD(substr(ctx_val.msisdn, 1, lengthof(ctx_val.msisdn) -1)));
+	rat_type := int2oct(g_pars.rat_type, 1);
+	charging_char := char2oct(oct2str('0000'O));  // f_create_session() uses hardcoded chg_car := '0000'O
+	nsapi := '01'O; // f_create_session() uses hardcoded bearer_id := 1
+	select (req_type) {
+		case (INITIAL_REQUEST) {
+			tpl := tr_DIAMETER(flags:='11000000'B, cmd_code:=Credit_Control,
+				avps := superset(
+					tr_AVP_SessionId,
+					tr_AVP_OriginHost(smf_origin_host),
+					tr_AVP_OriginRealm(mp_diam_realm),
+					tr_AVP_DestinationRealm(mp_diam_realm),
+					tr_AVP_AuthAppId(int2oct(c_DIAMETER_CREDIT_CONTROL_AID, 4)),
+					tr_AVP_ServiceContextId,
+					tr_AVP_CcReqType(req_type),
+					tr_AVP_CcReqNum(?),
+					tr_AVP_EventTimestamp(?),
+					tr_AVP_SubcrId({tr_AVP_SubcrIdType(END_USER_IMSI), tr_AVP_SubcrIdData(imsi)}),
+					tr_AVP_SubcrId({tr_AVP_SubcrIdType(END_USER_E164), tr_AVP_SubcrIdData(msisdn)}),
+					tr_AVP_RequestedAction(DIRECT_DEBITING),
+					tr_AVP_3GPP_AoCRequestType,
+					tr_AVP_MultipleServicesIndicator,
+					tr_AVP_Multiple_Services_Credit_Control(content := superset(
+						tr_AVP_Requested_Service_Unit,
+						tr_AVP_Used_Service_Unit,
+						tr_AVP_3GPP_QoS_Information,
+						tr_AVP_GI_3GPP_RatType(rat_type)
+					)),
+					tr_AVP_3GPP_ServiceInformation(content := superset(
+						tr_AVP_3GPP_PSInformation(content := superset(
+							tr_AVP_3GPP_ChargingId,
+							tr_AVP_3GPP_PDPType((IPv4,IPv6,IPv4v6)),
+							tr_AVP_3GPP_PDPAddress(tr_AVP_Address((IP,IP6), ?)),
+							tr_AVP_3GPP_SGSNAddress(tr_AVP_Address(IP, f_inet_addr(mp_pcrf_local_ip))),
+							tr_AVP_3GPP_GGSNAddress(tr_AVP_Address(IP, f_inet_addr(mp_pgw_hostname))),
+							tr_AVP_3GPP_CalledStationId,
+							tr_AVP_3GPP_SelectionMode,
+							tr_AVP_3GPP_ChargingCharacteristics(charging_char),
+							tr_AVP_3GPP_SGSNMCCMNC,
+							tr_AVP_3GPP_NSAPI(nsapi),
+							/*We don't yet send MS_Tz in CreateSessionReq:
+							tr_AVP_3GPP_MS_TimeZone,*/
+							tr_AVP_3GPP_ULI/*,
+							We don't yet send IMEI in CreateSessionReq:
+							tr_AVP_UserEquipmentInfo({
+								tr_AVP_UserEquipmentInfoType(IMEISV),
+								tr_AVP_UserEquipmentInfoValue(imeisv)
+							})*/
+						))
+					))
+				));
+		}
+		case (UPDATE_REQUEST) {
+			tpl := tr_DIAMETER(flags:='11000000'B, cmd_code:=Credit_Control,
+				avps := superset(
+					tr_AVP_SessionId,
+					tr_AVP_OriginHost(smf_origin_host),
+					tr_AVP_OriginRealm(mp_diam_realm),
+					tr_AVP_DestinationRealm(mp_diam_realm),
+					tr_AVP_AuthAppId(int2oct(c_DIAMETER_CREDIT_CONTROL_AID, 4)),
+					tr_AVP_ServiceContextId,
+					tr_AVP_CcReqType(req_type),
+					tr_AVP_CcReqNum(?),
+					tr_AVP_DestinationHost(?),
+					tr_AVP_EventTimestamp(?),
+					tr_AVP_SubcrId({tr_AVP_SubcrIdType(END_USER_IMSI), tr_AVP_SubcrIdData(imsi)}),
+					tr_AVP_SubcrId({tr_AVP_SubcrIdType(END_USER_E164), tr_AVP_SubcrIdData(msisdn)}),
+					tr_AVP_RequestedAction(DIRECT_DEBITING),
+					tr_AVP_3GPP_AoCRequestType,
+					tr_AVP_MultipleServicesIndicator,
+					tr_AVP_Multiple_Services_Credit_Control(content := superset(
+						tr_AVP_Requested_Service_Unit,
+						tr_AVP_Used_Service_Unit,
+						tr_AVP_3GPP_Reporting_Reason,
+						tr_AVP_3GPP_QoS_Information,
+						tr_AVP_GI_3GPP_RatType(rat_type)
+					)),
+					tr_AVP_3GPP_ServiceInformation(content := superset(
+						tr_AVP_3GPP_PSInformation(content := superset(
+							tr_AVP_3GPP_ChargingId,
+							/* tr_AVP_3GPP_PDPType, Only in INIT */
+							tr_AVP_3GPP_PDPAddress(tr_AVP_Address((IP,IP6), ?)),
+							tr_AVP_3GPP_SGSNAddress(tr_AVP_Address(IP, f_inet_addr(mp_pcrf_local_ip))),
+							tr_AVP_3GPP_GGSNAddress(tr_AVP_Address(IP, f_inet_addr(mp_pgw_hostname))),
+							tr_AVP_3GPP_CalledStationId,
+							tr_AVP_3GPP_SelectionMode,
+							tr_AVP_3GPP_ChargingCharacteristics(charging_char),
+							tr_AVP_3GPP_SGSNMCCMNC,
+							tr_AVP_3GPP_NSAPI(nsapi),
+							/*We don't yet send MS_Tz in CreateSessionReq:
+							tr_AVP_3GPP_MS_TimeZone,*/
+							tr_AVP_3GPP_ULI/*,
+							We don't yet send IMEI in CreateSessionReq:
+							tr_AVP_UserEquipmentInfo({
+								tr_AVP_UserEquipmentInfoType(IMEISV),
+								tr_AVP_UserEquipmentInfoValue(imeisv)
+							})*/
+						))
+					))
+				));
+		}
+		case (TERMINATION_REQUEST) {
+			tpl := tr_DIAMETER(flags:='11000000'B, cmd_code:=Credit_Control,
+				avps := superset(
+					tr_AVP_SessionId,
+					tr_AVP_OriginHost(smf_origin_host),
+					tr_AVP_OriginRealm(mp_diam_realm),
+					tr_AVP_DestinationRealm(mp_diam_realm),
+					tr_AVP_AuthAppId(int2oct(c_DIAMETER_CREDIT_CONTROL_AID, 4)),
+					tr_AVP_ServiceContextId,
+					tr_AVP_CcReqType(req_type),
+					tr_AVP_CcReqNum(?),
+					tr_AVP_DestinationHost(?),
+					tr_AVP_EventTimestamp(?),
+					tr_AVP_SubcrId({tr_AVP_SubcrIdType(END_USER_IMSI), tr_AVP_SubcrIdData(imsi)}),
+					tr_AVP_SubcrId({tr_AVP_SubcrIdType(END_USER_E164), tr_AVP_SubcrIdData(msisdn)}),
+					tr_AVP_TerminationCause(?),
+					tr_AVP_RequestedAction(DIRECT_DEBITING),
+					tr_AVP_3GPP_AoCRequestType,
+					tr_AVP_MultipleServicesIndicator,
+					tr_AVP_Multiple_Services_Credit_Control(content := superset(
+						/* tr_AVP_Requested_Service_Unit, Only in INIT and UPDATE */
+						tr_AVP_Used_Service_Unit,
+						tr_AVP_3GPP_QoS_Information,
+						tr_AVP_GI_3GPP_RatType(rat_type)
+					)),
+					tr_AVP_3GPP_ServiceInformation(content := superset(
+						tr_AVP_3GPP_PSInformation(content := superset(
+							tr_AVP_3GPP_ChargingId,
+							/* tr_AVP_3GPP_PDPType, Only in INIT */
+							tr_AVP_3GPP_PDPAddress(tr_AVP_Address((IP,IP6), ?)),
+							tr_AVP_3GPP_SGSNAddress(tr_AVP_Address(IP, f_inet_addr(mp_pcrf_local_ip))),
+							tr_AVP_3GPP_GGSNAddress(tr_AVP_Address(IP, f_inet_addr(mp_pgw_hostname))),
+							tr_AVP_3GPP_CalledStationId,
+							tr_AVP_3GPP_SelectionMode,
+							tr_AVP_3GPP_ChargingCharacteristics(charging_char),
+							tr_AVP_3GPP_SGSNMCCMNC,
+							tr_AVP_3GPP_NSAPI(nsapi),
+							/*We don't yet send MS_Tz in CreateSessionReq:
+							tr_AVP_3GPP_MS_TimeZone,*/
+							tr_AVP_3GPP_ULI/*,
+							We don't yet send IMEI in CreateSessionReq:
+							tr_AVP_UserEquipmentInfo({
+								tr_AVP_UserEquipmentInfoType(IMEISV),
+								tr_AVP_UserEquipmentInfoValue(imeisv)
+							})*/
+						))
+					))
+				));
+		}
+	}
+	return tpl;
+}
+
 private altstep as_DIA_Gy_CCR(DCC_NONE_CC_Request_Type req_type) runs on PGW_Session_CT {
 	var PDU_DIAMETER rx_dia;
-	[] Gy.receive(tr_DIA_Gy_CCR(req_type := req_type)) -> value rx_dia {
+	[] Gy.receive(f_tr_DIA_Gy_CCR(req_type := req_type)) -> value rx_dia {
 		var template (value) PDU_DIAMETER tx_dia;
 		var template (omit) AVP avp;
 		var octetstring sess_id;
@@ -421,7 +586,7 @@
 	fteid_u_ie := ts_GTP2C_FTEID(FTEID_IF_S5S8_SGW_GTPU, g_teid, 2,
 					f_inet_addr(mp_local_hostname_u), omit);
 	var template (value) PDU_GTPCv2 g2c :=
-		ts_GTP2C_CreateSessionReq(imsi := g_pars.imsi, msisdn := oct2hex('1234567890'O), rat_type := 6,
+		ts_GTP2C_CreateSessionReq(imsi := g_pars.imsi, msisdn := g_pars.msisdn, rat_type := 6,
 					  sender_fteid := fteid_c_ie,
 					  apn := f_enc_dns_hostname(g_pars.apn),
 					  pdn_type := g_pars.pdn_type, teid_list := { fteid_u_ie },
diff --git a/pgw/gen_links.sh b/pgw/gen_links.sh
index b061fea..c8333c7 100755
--- a/pgw/gen_links.sh
+++ b/pgw/gen_links.sh
@@ -6,6 +6,7 @@
 
 DIR=$BASEDIR/titan.Libraries.TCCUsefulFunctions/src
 FILES="TCCInterface_Functions.ttcn TCCConversion_Functions.ttcn TCCConversion.cc TCCInterface.cc TCCInterface_ip.h"
+FILES+=" TCCEncoding_Functions.ttcn TCCEncoding.cc " # BCD coding
 gen_links $DIR $FILES
 
 DIR=$BASEDIR/titan.TestPorts.Common_Components.Socket-API/src
diff --git a/pgw/regen_makefile.sh b/pgw/regen_makefile.sh
index ce59dfb..5edcaef 100755
--- a/pgw/regen_makefile.sh
+++ b/pgw/regen_makefile.sh
@@ -19,6 +19,7 @@
 	Native_FunctionDefs.cc
 	TCCConversion.cc
 	TCCInterface.cc
+	TCCEncoding.cc
 	UDP_EncDec.cc
 	UECUPS_CodecPort_CtrlFunctDef.cc
 "