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;

/*******************************
 * S6a 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 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) 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(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)//,
		// 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 */
