/* GPRS RLC/MAC Control Messages as per 3GPP TS 44.060 manually transcribed from the CSN.1 syntax, as no CSN.1
 * tool for Eclipse TITAN could be found.  Implements only the minimum necessary messages for Osmocom teseting
 * purposes. */

/* (C) 2017-2018 Harald Welte <laforge@gnumonks.org>
 * contributions by sysmocom - s.f.m.c. GmbH
 * 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
 */

module RLCMAC_CSN1_Templates {
	import from General_Types all;
	import from Osmocom_Types all;
	import from GSM_Types all;
	import from MobileL3_GMM_SM_Types all;
	import from RLCMAC_CSN1_Types all;

	template (value) RlcmacUlCtrlMsg ts_RlcMacUlCtrl_PKT_CTRL_ACK(GprsTlli tlli,
						CtrlAck ack := MS_RCVD_TWO_RLC_SAME_RTI_DIFF_RBSN) := {
		msg_type := PACKET_CONTROL_ACK,
		u := {
			ctrl_ack := {
				tlli := tlli,
				ctrl_ack := ack
			}
		}
	}

	const ILevel iNone := {
		presence := '0'B,
		i_level := omit
	}
	const ChannelQualityReport c_ChQualRep_default := {
		c_value := 0,
		rxqual := 0,
		sign_var := 0,
		i_levels := { iNone, iNone, iNone, iNone, iNone, iNone, iNone, iNone }
	}
	template (value) RlcmacUlCtrlMsg ts_RlcMacUlCtrl_PKT_DL_ACK(uint5_t dl_tfi,
								    AckNackDescription andesc,
					ChannelQualityReport qual_rep := c_ChQualRep_default) := {
		msg_type := PACKET_DL_ACK_NACK,
		u := {
			dl_ack_nack := {
				dl_tfi := dl_tfi,
				ack_nack_desc := andesc,
				chreq_desc_presence := '0'B,
				chreq_desc := omit,
				ch_qual_rep := qual_rep
			}
		}
	}

	private function f_presence_bit_MSRadioAccessCapabilityV(template (omit) MSRadioAccessCapabilityV ms_rac) return BIT1 {
		if (istemplatekind(ms_rac, "omit")) {
			return '0'B;
		}
		return '1'B;
	}

	private function f_template_MSRadioAccessCapabilityV_to_MSRadioAccCap2(template (omit) MSRadioAccessCapabilityV ms_rac) return template (omit) MSRadioAccCap2 {
		var template (omit) MSRadioAccCap2 ms_rac2 := omit;
		if (istemplatekind(ms_rac, "omit")) {
			return ms_rac2;
		}
		ms_rac2 := { msRadioAccessCapabilityV := ms_rac };
		return ms_rac2;
	}

	const ChannelReqDescription c_ChReqDesc_default := {
		peak_tput_class := 0,
		priority := 0,
		rlc_mode := RLC_MODE_ACKNOWLEDGED,
		llc_pdu_type := LLC_PDU_IS_NOT_SACK_OR_ACK,
		RlcOctetCount := 0
	}

	/* TS 44.060 sec 11.2.16 */
	template (value) RlcmacUlCtrlMsg ts_RlcMacUlCtrl_PKT_RES_REQ(GprsTlli tlli,
						     template (omit) MSRadioAccessCapabilityV ms_rac,
						     ChannelReqDescription ch_req_desc := c_ChReqDesc_default,
						     RlcAccessType acc_type := RLC_ACC_TYPE_TWO_PHASE)
	:= {
		msg_type := PACKET_RESOURCE_REQUEST,
		u := {
			resource_req := {
				acc_type_presence := '1'B,
				acc_type := acc_type,
				id_type := '1'B,
				id := { tlli := tlli },
				ms_rac2_presence := f_presence_bit_MSRadioAccessCapabilityV(ms_rac),
				ms_rac2 := f_template_MSRadioAccessCapabilityV_to_MSRadioAccCap2(ms_rac),
				ch_req_desc := ch_req_desc,
				change_mark_presence := '0'B,
				change_mark := omit,
				C_val := '000000'B,
				sign_var_presence := '0'B,
				sign_var := omit,
				I_levels := {
					iNone, iNone, iNone, iNone,
					iNone, iNone, iNone, iNone
				}
			}
		}
	};

	private function f_presence_bit_tfi(template uint5_t tfi) return BIT1 {
		if (istemplatekind(tfi, "omit")) {
			return '0'B;
		}
		return '1'B;
	}

	template DynamicAllocation tr_DynamicAllocation(template uint5_t tfi:= ?) := {
		extd_dyn_alloc := ?,
		p0_present := ?,
		p0 := *,
		pr_mode := *,
		usf_granularity := ?,
		ul_tfi_ass_present := f_presence_bit_tfi(tfi),
		ul_tfi_assignment := tfi,
		reserved := '0'B,
		tbf_starting_time_present := ?,
		tbf_starting_time := *,
		ts_allocation := ?
	};

	template PktUlAssGprs tr_PktUlAssGprsDynamic(template DynamicAllocation dyn_alloc := ?) := {
		ch_coding_cmd := ?,
		tlli_block_chan_coding := ?,
		pkt_ta := ?,
		freq_par_present := ?,
		freq_par := *,
		alloc_present := '01'B,
		dyn_block_alloc := dyn_alloc,
		sgl_block_alloc := omit
	};

	template PktUlAssEgprs tr_PktUlAssEgprsDynamic(template DynamicAllocation dyn_alloc := ?) := {
		dual_carrier := '00'B,
		tlli_present := ?,
		tlli := *,
		compact_reduced_ma_present := ?,
		compact_reduced_ma := *,
		chan_coding_cmd := ?,
		resegment := ?,
		window_size := ?,
		ats_present := ?,
		ats := *, /* ? */
		arac_retrans_req := ?,
		tlli_block_chan_coding := ?,
		bep_period2_present := ?,
		bep_period2 := *,
		pkt_ta := ?,
		pkt_ext_ta_present := ?,
		pkt_ext_ta := *,
		freq_par_present := ?,
		freq_par := *,
		alloc_present := ?,
		dyn_block_alloc := dyn_alloc,
		multi_block_alloc := omit
	};

	template AckNackDescription tr_AckNackDescription(template BIT1 final_ack := ?) := {
		final_ack := final_ack,
		starting_seq_nr := ?,
		receive_block_bitmap := ?
	};

	template UlAckNackGprsAdditionsRel99 tr_UlAckNackGprsAdditionsRel99(template boolean tbf_est := ?) := {
		ext_pkt_ta_present := ?,
		ext_pkt_ta := *,
		tbf_est := tbf_est
	};

	template UlAckNackGprs tr_UlAckNackGprs(template GprsTlli tlli := *,
						template AckNackDescription acknack_desc := ?,
						template UlAckNackGprsAdditionsRel99 rel99 := *) := {
		ch_coding_cmd := ?,
		ack_nack_desc := acknack_desc,
		cont_res_tlli_present := ?,
		cont_res_tlli := tlli,
		pkt_ta_present := ?,
		pkt_ta := *,
		pwr_ctrl_present := ?,
		pwr_ctrl := *,
		extension_bits_present := ?,
		extension_bits := *,
		not_used := '0'B,
		rel99_present := ?,
		rel99 := rel99
	};

	template UlAckNackEgprs tr_UlAckNackEgprs(template GprsTlli tlli := *) := {
		msg_excape := '00'B,
		ch_coding_cmd := ?,
		resegment := ?,
		preemptive_tx := ?,
		prr_retrans_req := ?,
		arac_retrans_req := ?,
		cont_res_tlli_present := ?,
		cont_res_tlli := tlli,
		tbf_est := ?,
		pkt_ta_present := ?,
		pkt_ta := *,
		pkt_ext_ta_present := ?,
		pkt_ext_ta := *,
		pwr_ctrl_present := ?,
		pwr_ctrl := *
	};

	template EgprsAckNackDescriptionIE ts_EgprsAckNackDescriptionIE(template EgprsAckNackDescription andesc) := {
		len_present := '1'B,
		len := 0, /* Overwritten by RAW encoder */
		acknack_desc := andesc
	}

} with { encode "RAW"; variant "FIELDORDER(msb)" variant "BYTEORDER(last)" };
