module DIAMETER_ts32_299_Templates {

/* (C) 2023 by sysmocom s.f.m.c. GmbH <info@sysmocom.de
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 *
 * Templates for AVPs and messages for TS 32.299
 */

import from General_Types all;
import from DIAMETER_Types all;
import from DIAMETER_Templates all;
import from Osmocom_Types all;
import from Misc_Helpers all;

/*******************************
 * Gy 3GPP TS 32.299 section 7
 *******************************/

/* Gy AID : 3GPP TS 32.299 7.1.6, RFC4006 3.1: c_DIAMETER_CREDIT_CONTROL_AID */

/* 3GPP TS 32.299  7.1.11 Result-Code AVP*/
type enumerated DIAMETER_ts32_229_Resultcode {
	/* transient */
	DIAMETER_END_USER_SERVICE_DENIED		(4010),
	DIAMETER_CREDIT_CONTROL_NOT_APPLICABLE 		(4011),
	DIAMETER_CREDIT_LIMIT_REACHED 			(4012),
	/* permanent */
	DIAMETER_AUTHORIZATION_REJECTED			(5003),
	DIAMETER_USER_UNKNOWN				(5030),
	DIAMETER_RATING_FAILED				(5031)
}

/* 3GPP TS 32.299 6.4.2 Credit-Control-Request */
template (present) PDU_DIAMETER
tr_DIA_Gy_CCR(template (present) DCC_NONE_CC_Request_Type req_type := INITIAL_REQUEST)
:= tr_DIAMETER(flags:='11000000'B, cmd_code:=Credit_Control,
	avps := superset(
		tr_AVP_SessionId,
		tr_AVP_OriginHost,
		tr_AVP_OriginRealm,
		tr_AVP_DestinationRealm,
		tr_AVP_AuthAppId(int2oct(c_DIAMETER_CREDIT_CONTROL_AID, 4)),
		tr_AVP_CcReqType(req_type),
		tr_AVP_CcReqNum(?)
	));

/* 3GPP TS 32.299 6.4.3 Credit-Control-Answer message */
template (value) PDU_DIAMETER
ts_DIA_Gy_CCA(template (value) UINT32 hbh_id, template (value) UINT32 ete_id,
	   template (value) octetstring sess_id,
	   template (value) DIAMETER_Resultcode res_code,
	   template (value) DCC_NONE_CC_Request_Type req_type,
	   template (value) AVP_Unsigned32 req_num)
:= ts_DIAMETER(flags:='01000000'B, cmd_code:=Credit_Control,
		app_id:=int2oct(c_DIAMETER_CREDIT_CONTROL_AID, 4), hbh_id:=hbh_id, ete_id:=ete_id,
	avps := {
		ts_AVP_SessionId(sess_id),
		ts_AVP_ResultCode(res_code),
		ts_AVP_OriginHost("ocs.localdomain"),
		ts_AVP_OriginRealm("localdomain"),
		ts_AVP_AuthAppId(int2oct(c_DIAMETER_CREDIT_CONTROL_AID, 4)),
		ts_AVP_CcReqType(req_type),
		ts_AVP_CcReqNum(req_num)//,
		// qos
		// default eps bearer qos
		// supported features
		// origin
	});
/* Same as ts_DIA_Gy_CCA, but with extra AVP to grant access for limited amount of seconds */
template (value) PDU_DIAMETER
ts_DIA_Gy_CCA_ValidityTime(template (value) UINT32 hbh_id, template (value) UINT32 ete_id,
	   template (value) octetstring sess_id,
	   template (value) DCC_NONE_CC_Request_Type req_type,
	   template (value) AVP_Unsigned32 req_num,
	   uint32_t validity_time)
:= ts_DIAMETER(flags:='01000000'B, cmd_code:=Credit_Control,
		app_id:=int2oct(c_DIAMETER_CREDIT_CONTROL_AID, 4), hbh_id:=hbh_id, ete_id:=ete_id,
	avps := {
		ts_AVP_SessionId(sess_id),
		ts_AVP_ResultCode(DIAMETER_SUCCESS),
		ts_AVP_OriginHost("ocs.localdomain"),
		ts_AVP_OriginRealm("localdomain"),
		ts_AVP_AuthAppId(int2oct(c_DIAMETER_CREDIT_CONTROL_AID, 4)),
		ts_AVP_CcReqType(req_type),
		ts_AVP_CcReqNum(req_num),
		ts_AVP_Multiple_Services_Credit_Control({
			ts_AVP_Validity_Time(validity_time),
			ts_AVP_Granted_Service_Unit({
				//ts_AVP_CC_Time(validity_time*2),
				ts_AVP_CC_Total_Octets(1000)
				})
			})
		//,
		// qos
		// default eps bearer qos
		// supported features
		// origin
	});
/* Same as ts_DIA_Gy_CCA_ValidityTime, but with extra AVP to grant access for limited amount of octets */
template (value) PDU_DIAMETER
ts_DIA_Gy_CCA_ValidityTimeVolumeThreshold(template (value) UINT32 hbh_id, template (value) UINT32 ete_id,
	   template (value) octetstring sess_id,
	   template (value) DCC_NONE_CC_Request_Type req_type,
	   template (value) AVP_Unsigned32 req_num,
	   uint32_t validity_time, uint32_t volume_threhsold)
:= ts_DIAMETER(flags:='01000000'B, cmd_code:=Credit_Control,
		app_id:=int2oct(c_DIAMETER_CREDIT_CONTROL_AID, 4), hbh_id:=hbh_id, ete_id:=ete_id,
	avps := {
		ts_AVP_SessionId(sess_id),
		ts_AVP_ResultCode(DIAMETER_SUCCESS),
		ts_AVP_OriginHost("ocs.localdomain"),
		ts_AVP_OriginRealm("localdomain"),
		ts_AVP_AuthAppId(int2oct(c_DIAMETER_CREDIT_CONTROL_AID, 4)),
		ts_AVP_CcReqType(req_type),
		ts_AVP_CcReqNum(req_num),
		ts_AVP_Multiple_Services_Credit_Control({
			ts_AVP_Validity_Time(validity_time),
			ts_AVP_Granted_Service_Unit({
				ts_AVP_CC_Total_Octets(volume_threhsold*100)
				}),
			ts_AVP_3GPP_VolumeQuotaThreshold(volume_threhsold)
			})
		//,
		// qos
		// default eps bearer qos
		// supported features
		// origin
	});

function f_validate_gy_cc_report(PDU_DIAMETER rx_dia, template (present) DCA_3GPP_Reporting_Reason repreason_exp := ?,
				 template (present) integer cc_time_exp := ?,
				 template (present) integer cc_in_oct_exp := ?,
				 template (present) integer cc_out_oct_exp := ?)
{
	var AVP multi_services_cc, used_service_unit;
	var AVP_Grouped multi_services_cc_data, used_service_unit_data;
	var template (omit) AVP repreason_tpl;
	var AVP repreason, cc_time, cc_in_oct, cc_out_oct;

	multi_services_cc := f_DIAMETER_get_avp_or_fail(rx_dia, c_AVP_Code_DCC_NONE_Multiple_Services_Credit_Control);
	multi_services_cc_data := valueof(multi_services_cc.avp_data.avp_DCC_NONE_Multiple_Services_Credit_Control);

	used_service_unit := f_AVP_Grouped_get_avp_or_fail(multi_services_cc_data, c_AVP_Code_DCC_NONE_Used_Service_Unit);
	used_service_unit_data := valueof(used_service_unit.avp_data.avp_DCC_NONE_Used_Service_Unit);

	/* Reporting-Reason can be either inside Multiple-Services-Credit-Control or inside Used-Service-Unit */
	repreason_tpl := f_AVP_Grouped_get_avp(multi_services_cc_data, c_AVP_Code_DCA_3GPP_Reporting_Reason);
	if (istemplatekind(repreason_tpl, "omit")) {
		repreason := f_AVP_Grouped_get_avp_or_fail(used_service_unit_data, c_AVP_Code_DCA_3GPP_Reporting_Reason);
	} else {
		repreason := valueof(repreason_tpl);
	}
	if (not match(repreason.avp_data.avp_DCA_3GPP_Reporting_Reason, repreason_exp)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			log2str("3GPP-Reporting-Reason mismatch ", repreason, " vs exp ", repreason_exp));
	}

	cc_time := f_AVP_Grouped_get_avp_or_fail(used_service_unit_data, c_AVP_Code_DCC_NONE_CC_Time);
	if (not match(oct2int(cc_time.avp_data.avp_DCC_NONE_CC_Time), cc_time_exp)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			log2str("3GPP-CC-Time mismatch ", cc_time, " vs exp ", cc_time_exp));
	}

	cc_in_oct := f_AVP_Grouped_get_avp_or_fail(used_service_unit_data, c_AVP_Code_DCC_NONE_CC_Input_Octets);
	if (not match(oct2int(cc_in_oct.avp_data.avp_DCC_NONE_CC_Input_Octets), cc_in_oct_exp)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			log2str("3GPP-CC-Input-Octets mismatch ", cc_in_oct, " vs exp ", cc_in_oct_exp));
	}

	cc_out_oct := f_AVP_Grouped_get_avp_or_fail(used_service_unit_data, c_AVP_Code_DCC_NONE_CC_Output_Octets);
	if (not match(oct2int(cc_out_oct.avp_data.avp_DCC_NONE_CC_Output_Octets), cc_out_oct_exp)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			log2str("3GPP-CC-Output-Octets mismatch ", cc_out_oct, " vs exp ", cc_out_oct_exp));
	}
}

} /* module */
