/* Encoding/Decoding routines for GSM System Information messages
 * according to 3GPP TS 44.018 Version 12.3.0 Release 12
 *
 * (C) 2018 Harald Welte <laforge@gnumonks.org>
 * 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 GSM_SystemInformation {

	import from General_Types all;
	import from GSM_Types all;
	import from GSM_RR_Types all;
	import from GSM_RestOctets all;
	import from Osmocom_Types all;

	type union ArfcnOrMaio {
		uint12_t	arfcn,
		MaioHsn		maio_hsn
	} with { variant "" };

	/* 24.008 10.5.1.1 */
	type uint16_t SysinfoCellIdentity;

	/* 44.018 10.5.2.1b */
	type octetstring CellChannelDescription with { variant "FIELDLENGTH(16)" };

	/* 44.018 10.5.2.3 */
	type enumerated CellOptions_DTX {
		MS_MAY_USE_UL_DTX	('00'B),
		MS_SHALL_USE_UL_DTX	('01'B),
		MS_SHALL_NOT_USE_UL_DTX	('10'B)
	} with { variant "FIELDLENGTH(2)" };
	type record CellOptions {
		boolean		dn_ind,
		boolean		pwrc,
		CellOptions_DTX	dtx,
		uint4_t		radio_link_tout_div4
	} with { variant "" };

	/* 44.018 10.5.2.3a */
	type record CellOptionsSacch {
		BIT1		dtx_ext,
		boolean		pwrc,
		BIT2		dtx,
		BIT4		radio_link_timeout
	} with { variant "" };

	/* 44.018 10.5.2.4 */
	type record CellSelectionParameters {
		uint3_t		cell_resel_hyst_2dB,
		uint5_t		ms_txpwr_max_cch,
		BIT1		acs,
		boolean		neci,
		uint6_t		rxlev_access_min
	} with { variant "" };

	/* 44.018 10.5.2.11 */
	type enumerated CtrlChanDesc_CC {
		CCHAN_DESC_1CCCH_NOT_COMBINED	('000'B),
		CCHAN_DESC_1CCCH_COMBINED	('001'B),
		CCHAN_DESC_2CCCH_NOT_COMBINED	('010'B),
		CCHAN_DESC_3CCCH_NOT_COMBINED	('100'B),
		CCHAN_DESC_4CCCH_NOT_COMBINED	('110'B)
	} with { variant "FIELDLENGTH(3)" };
	type enumerated CBQ3 {
		CBQ3_IU_MODE_NOT_SUPPORTED	('00'B),
		CBQ3_IU_MODE_MS_BARRED		('01'B),
		CBQ3_IU_MODE_NOT_BARRED		('10'B)
	} with { variant "FIELDLENGTH(2)" };
	type record ControlChannelDescription {
		boolean		msc_r99,
		boolean		att,
		uint3_t		bs_ag_blks_res,
		CtrlChanDesc_CC	ccch_conf,
		boolean		si22ind,
		CBQ3		cbq3,
		BIT2		spare,
		uint3_t		bs_pa_mfrms, /* off by 2 */
		uint8_t		t3212
	} with { variant "" };

	template ControlChannelDescription t_ControlChannelDescription := { ?, ?, ?, ?, ?, ?, '00'B, ?, ? };

	/* 44.018 10.5.2.22 */
	type octetstring NeighbourCellDescription with { variant "FIELDLENGTH(16)" };

	/* 44.018 10.5.2.22a */
	type octetstring NeighbourCellDescription2 with { variant "FIELDLENGTH(16)" };

	type bitstring AccessControlClass with { variant "FIELDLENGTH(16), BYTEORDER(last)" };

	/* 44.018 10.5.2.29 */
	type enumerated RachCtrlPar_MR {
		RACH_MAX_RETRANS_1	('00'B),
		RACH_MAX_RETRANS_2	('01'B),
		RACH_MAX_RETRANS_4	('10'B),
		RACH_MAX_RETRANS_7	('11'B)
	} with { variant "FIELDLENGTH(2)" };
	type record RachControlParameters {
		RachCtrlPar_MR	max_retrans,
		BIT4		tx_integer,
		boolean		cell_barr_access,
		boolean		re_not_allowed,
		AccessControlClass acc
	} with { variant (acc) "FIELDLENGTH(16)" };

	/* 44.018 9.1.31 */
	type record SystemInformationType1 {
		CellChannelDescription	cell_chan_desc,
		RachControlParameters	rach_control,
		RestOctets		rest_octets length(0..1)
	} with { variant "" };

	/* 44.018 9.1.32 */
	type record SystemInformationType2 {
		NeighbourCellDescription bcch_freq_list,
		BIT8			ncc_permitted,
		RachControlParameters	rach_control
	} with { variant "" };

	/* 44.018 9.1.33 */
	type record SystemInformationType2bis {
		NeighbourCellDescription	extd_bcch_freq_list,
		RachControlParameters		rach_control,
		RestOctets			rest_octets length(0..1)
	} with { variant "" };

	/* 44.018 9.1.34 */
	type record SystemInformationType2ter {
		NeighbourCellDescription2	extd_bcch_freq_list,
		RestOctets			rest_octets length(0..4)
	} with { variant "" };

	type record SystemInformationType2quater {
		SI2quaterRestOctets	rest_octets
	} with { variant "" };

	/* 44.018 9.1.35 */
	type record SystemInformationType3 {
		SysinfoCellIdentity		cell_id,
		LocationAreaIdentification	lai,
		ControlChannelDescription	ctrl_chan_desc,
		CellOptions			cell_options,
		CellSelectionParameters		cell_sel_par,
		RachControlParameters		rach_control,
		SI3RestOctets			rest_octets
	} with { variant "" };

	template SystemInformationType3 t_SI3 := {
		cell_id := ?,
		lai := ?,
		ctrl_chan_desc := t_ControlChannelDescription,
		cell_options := ?,
		cell_sel_par := ?,
		rach_control := ?,
		rest_octets := ?
	};


	/* 44.018 9.1.36 */
	type record SystemInformationType4 {
		LocationAreaIdentification	lai,
		CellSelectionParameters		cell_sel_par,
		RachControlParameters		rach_control,
		ChannelDescriptionTV		cbch_chan_desc optional,
		MobileAllocationTLV		cbch_mobile_alloc optional,
		SI4RestOctets			rest_octets /* see 10.5.2.35 */
	} with { variant "TAG(cbch_chan_desc, iei = '64'O; cbch_mobile_alloc, iei = '72'O)" };

	/* 44.018 9.1.37 */
	type record SystemInformationType5 {
		NeighbourCellDescription	bcch_freq_list
	} with { variant "" };

	/* 44.018 9.1.38 */
	type record SystemInformationType5bis {
		NeighbourCellDescription	extd_bcch_freq_list
	} with { variant "" };

	/* 44.018 9.1.39 */
	type record SystemInformationType5ter {
		NeighbourCellDescription2	extd_bcch_freq_list
	} with { variant "" };

	/* 44.018 9.1.40 */
	type record SystemInformationType6 {
		SysinfoCellIdentity		cell_id,
		LocationAreaIdentification	lai,
		CellOptionsSacch		cell_options,
		BIT8				ncc_permitted,
		RestOctets			rest_octets length(0..7)
	} with { variant "" };

	/* 44.018 9.1.43a */
	type record SystemInformationType13 {
		SI13RestOctets			rest_octets
	} with { variant "" };

	type union SystemInformationUnion {
		SystemInformationType1		si1,
		SystemInformationType2		si2,
		SystemInformationType2bis	si2bis,
		SystemInformationType2ter	si2ter,
		SystemInformationType2quater	si2quater,
		SystemInformationType3		si3,
		SystemInformationType4		si4,
		SystemInformationType5		si5,
		SystemInformationType5bis	si5bis,
		SystemInformationType5ter	si5ter,
		SystemInformationType6		si6,
		SystemInformationType13		si13,
		octetstring			other
	} with { variant "" };

	type record SystemInformation {
		RrHeader			header,
		SystemInformationUnion		payload
	} with { variant (payload) "CROSSTAG(si1, header.message_type = SYSTEM_INFORMATION_TYPE_1;
			      si2, header.message_type = SYSTEM_INFORMATION_TYPE_2;
			      si2bis, header.message_type = SYSTEM_INFORMATION_TYPE_2bis;
			      si2ter, header.message_type = SYSTEM_INFORMATION_TYPE_2ter;
			      si2quater, header.message_type = SYSTEM_INFORMATION_TYPE_2quater;
			      si3, header.message_type = SYSTEM_INFORMATION_TYPE_3;
			      si4, header.message_type = SYSTEM_INFORMATION_TYPE_4;
			      si5, header.message_type = SYSTEM_INFORMATION_TYPE_5;
			      si5bis, header.message_type = SYSTEM_INFORMATION_TYPE_5bis;
			      si5ter, header.message_type = SYSTEM_INFORMATION_TYPE_5ter;
			      si6, header.message_type = SYSTEM_INFORMATION_TYPE_6;
			      si13, header.message_type = SYSTEM_INFORMATION_TYPE_13;
			      other, OTHERWISE;
			)" };

	external function enc_SystemInformationNoPad(in SystemInformation si) return octetstring
		with { extension "prototype(convert) encode(RAW)" };
	external function dec_SystemInformation(in octetstring stream) return SystemInformation
		with { extension "prototype(convert) decode(RAW)" };

	/* Due to a buggy nature of TITAN's padding attributes, we have to apply padding manually. */
	function enc_SystemInformation(in SystemInformation si) return octetstring
	{
		var octetstring si_enc := enc_SystemInformationNoPad(si);

		/* Resulting message length depends on SI Type */
		select (si.header.message_type) {
		case (SYSTEM_INFORMATION_TYPE_5,
		      SYSTEM_INFORMATION_TYPE_5bis,
		      SYSTEM_INFORMATION_TYPE_5ter) {
			/* SACCH: no Rest Octets, return 'as-is' */
			return si_enc;
			}
		case (SYSTEM_INFORMATION_TYPE_6) {
			/* SACCH: pad to 19 octets, leave room for L1/LAPDm headers */
			return f_pad_oct(si_enc, 19, '2B'O);
			}
		case else {
			/* BCCH: pad to 23 octets */
			return f_pad_oct(si_enc, 23, '2B'O);
			}
		}
	}

	external function dec_SystemInformationSafeBT(in octetstring stream, out SystemInformation si)
		return integer /* Decoding result: successful (0) or unsuccessful (1) */
		with { extension "prototype(backtrack) decode(RAW)" };

	/* Some types of System Information (mostly the Rest Octets) are not fully implemented,
	 * so calling the generic dec_SystemInformation() may result in a DTE.  This function
	 * additionally checks RR Protocol Discriminator, and should be used in the most cases. */
	function dec_SystemInformationSafe(in octetstring stream, out SystemInformation si)
	return integer {
		/* Try to decode a given octetstring as System Information */
		if (dec_SystemInformationSafeBT(stream, si) != 0) {
			log("Failed to decode (RR) System Information: ", stream);
			return 1;
		}

		/* Check the protocol discriminator (we expect RR messages) */
		if (si.header.rr_protocol_discriminator != bit2int('0110'B)) {
			log("Protocol discriminator is not RR (!= '0110'B): ",
			    si.header.rr_protocol_discriminator);
			return 1;
		}

		return 0;
	}

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