/* Encoding/Decoding routines for GSM System Information messages
 * according to 3GPP TS 44.018 Version 12.3.0 Release 12 */

/* (C) 2017 by Harald Welte <laforge@gnumonks.org> */

module GSM_Types {

	import from General_Types all;
	import from Osmocom_Types all;

	type integer GsmArfcn (0..1023);
	type integer UmtsArfcn (0..16383);
	type integer UmtsScramblingCode (0..511);
	const integer GsmMaxFrameNumber := 26*51*2048;
	type integer GsmFrameNumber (0..GsmMaxFrameNumber);
	type integer GsmRxLev (0..63);
	type integer GsmTsc (0..7) with { variant "FIELDLENGTH(8)" };
	type uint32_t GsmTmsi;
	type OCT4 GprsTlli;
	type hexstring GsmMcc length(3);
	type hexstring GsmMnc length(2 .. 3);
	type uint16_t GsmLac;
	type uint16_t GsmCellId;

	type enumerated GprsCodingScheme {
		CS1, CS2, CS3, CS4
	};

	function f_gprs_blocksize(GprsCodingScheme cs) return integer {
		select (cs) {
		case (CS1) { return 22 }
		case (CS2) { return 32 }
		case (CS3) { return 38 }
		case (CS3) { return 52 }
		case else {
			setverdict(fail, "Invalid GPRS CS ", cs);
			return -1;
			}
		}
	}

	/* 10.5.2.8 */
	type enumerated ChannelNeeded {
		CHAN_NEED_ANY	(0),
		CHAN_NEED_SDCCH	(1),
		CHAN_NEED_TCH_F	(2),
		CHAN_NEED_TCH_H	(3)
	} with { variant "FIELDLENGTH(2)" };
	type record ChannelNeeded12 {
		ChannelNeeded	second,
		ChannelNeeded	first
	} with { variant "" };


	/* TS 48.058 9.3.1 Channel Number IE */
	type enumerated RslChanNr0 {
		RSL_CHAN_NR_INVALID	('00000'B),
		RSL_CHAN_NR_Bm_ACCH	('00001'B),
		RSL_CHAN_NR_BCCH	('10000'B),
		RSL_CHAN_NR_RACH	('10001'B),
		RSL_CHAN_NR_PCH_AGCH	('10010'B),
		RSL_CHAN_NR_OSMO_PDCH	('11000'B)
	} with { variant "FIELDLENGTH(5)" variant "FIELDORDER(msb)" };

	type record RslChanNr2 {
		BIT4		tag ('0001'B),
		uint1_t		sub_chan
	} with { variant "FIELDLENGTH(5)" variant "FIELDORDER(msb)" };

	type record RslChanNr4 {
		BIT3		tag ('001'B),
		uint2_t		sub_chan
	} with { variant "FIELDLENGTH(5)" variant "FIELDORDER(msb)" };

	type record RslChanNr8 {
		BIT2		tag ('01'B),
		uint3_t		sub_chan
	} with { variant "FIELDLENGTH(5)" variant "FIELDORDER(msb)" };

	type union RslChanNrU {
		RslChanNr0	ch0,
		RslChanNr2	lm,
		RslChanNr4	sdcch4,
		RslChanNr8	sdcch8
	} with {
		variant "TAG(lm, tag = '0001'B;
			     sdcch4, tag = '001'B;
			     sdcch8, tag = '01'B;
			     ch0, OTHERWISE)"
		variant "FIELDLENGTH(5)"
		variant "FIELDORDER(msb)"
	};

	type record RslChannelNr {
		RslChanNrU	u,
		uint3_t		tn
	} with { variant "FIELDLENGTH(8)" variant "FIELDORDER(msb)" };

	template RslChannelNr t_RslChanNr0(template uint3_t tn, template RslChanNr0 cht) := {
		u := { ch0 := cht },
		tn := tn
	}

	template RslChannelNr t_RslChanNr_RACH(template uint3_t tn) := t_RslChanNr0(tn, RSL_CHAN_NR_RACH);
	template RslChannelNr t_RslChanNr_BCCH(template uint3_t tn) := t_RslChanNr0(tn, RSL_CHAN_NR_BCCH);
	template RslChannelNr t_RslChanNr_PCH_AGCH(template uint3_t tn) := t_RslChanNr0(tn, RSL_CHAN_NR_PCH_AGCH);
	template RslChannelNr t_RslChanNr_Bm(template uint3_t tn) := t_RslChanNr0(tn, RSL_CHAN_NR_Bm_ACCH);
	template RslChannelNr t_RslChanNr_PDCH(template uint3_t tn) := t_RslChanNr0(tn, RSL_CHAN_NR_OSMO_PDCH);
	template RslChannelNr t_RslChanNr_Lm(template uint3_t tn, template uint1_t sub_slot) := {
		u := { lm := { tag := '0001'B, sub_chan := sub_slot } },
		tn := tn
	}
	template RslChannelNr t_RslChanNr_SDCCH4(template uint3_t tn, template uint2_t sub_slot) := {
		u := { sdcch4 := { tag := '001'B, sub_chan := sub_slot } },
		tn := tn
	}
	template RslChannelNr t_RslChanNr_SDCCH8(template uint3_t tn, template uint3_t sub_slot) := {
		u := { sdcch8 := { tag := '01'B, sub_chan := sub_slot } },
		tn := tn
	}

	/* TS 48.058 9.3.2 Link ID */
	type enumerated RslLinkIdC {
		FACCH_SDCCH	(0),
		SACCH		(1)
	} with { variant "FIELDLENGTH(2)" };

	type enumerated RslSapi0Prio {
		SAPI0_PRIO_NORMAL	(0),
		SAPI0_PRIO_HIGH		(1),
		SAPI0_PRIO_LOW		(2)
	} with { variant "FIELDLENGTH(2)" };

	type uint3_t GsmSapi;

	type record RslLinkId {
		RslLinkIdC	c,
		boolean		na,
		RslSapi0Prio	prio,
		GsmSapi		sapi
	} with { variant "" };

	template RslLinkId tr_RslLinkId := {
		c := ?,
		na := ?,
		prio := ?,
		sapi := ?
	};

	template RslLinkId tr_RslLinkID_DCCH(template GsmSapi sapi) modifies tr_RslLinkId := {
		c := FACCH_SDCCH,
		na := false,
		sapi := sapi
	};

	template RslLinkId tr_RslLinkID_SACCH(template GsmSapi sapi) modifies tr_RslLinkId := {
		c := SACCH,
		na := false,
		sapi := sapi
	};

	template (value) RslLinkId ts_RslLinkID_DCCH(GsmSapi sapi) := {
		c := FACCH_SDCCH,
		na := false,
		prio := SAPI0_PRIO_NORMAL,
		sapi := sapi
	};

	template (value) RslLinkId ts_RslLinkID_SACCH(GsmSapi sapi) := {
		c := SACCH,
		na := false,
		prio := SAPI0_PRIO_NORMAL,
		sapi := sapi
	};

	function f_hex_is_odd_length(hexstring digits) return bitstring {
		if (lengthof(digits) rem 2 == 1) {
			return '1'B;
		} else {
			return '0'B;
		}
	}

/* Convert RF signal level in dBm to RxLev (TS 45.008 Chapter 8.1.4) */
function dbm2rxlev(integer dbm) return uint6_t {
	var integer rxlev := dbm + 110;
	if (rxlev > 63) {
		rxlev := 63;
	} else if (rxlev < 0) {
		rxlev := 0;
	}
	return rxlev;
}

function rxlev2dbm(uint6_t rxlev) return integer {
	return -110 + rxlev;
}

/* convert BER to RxQual value (TS 45.008 Chapter 8.2.4 */
function ber2rxqual(float ber) return uint3_t {
	if (ber < 0.2) {
		return 0;
	} else if (ber < 0.4) {
		return 1;
	} else if (ber < 0.8) {
		return 2;
	} else if (ber < 1.6) {
		return 3;
	} else if (ber < 3.2) {
		return 4;
	} else if (ber < 6.4) {
		return 5;
	} else if (ber < 12.8) {
		return 6;
	} else {
		return 7;
	}
}

/* convert RxQual to BER (TS 45.008 Chapter 8.2.4 */
function rxqual2ber(uint3_t rxqual) return float {
	select (rxqual) {
	case (0) { return 0.14 }
	case (1) { return 0.28 }
	case (2) { return 0.57 }
	case (3) { return 1.13 }
	case (4) { return 2.26 }
	case (5) { return 4.53 }
	case (6) { return 9.05 }
	case (7) { return 18.10 }
	case else { return 1000.0 }
	}
}

const float GSM_FRAME_DURATION := 0.12/26.0; /* 4.615 ms */
const float GSM51_MFRAME_DURATION := 51.0 * GSM_FRAME_DURATION; /* 235.365 ms */
const float GSM51_MFRAMES_PER_SEC := 1.0 / GSM51_MFRAME_DURATION; /* 4.248 */

/* number of downlink CCCH blocks per second */
function f_ccch_blocks_per_mframe(boolean combined_ccch) return integer {
	if (not combined_ccch) {
		/* 9 blocks per 51 multiframe */
		return 9;
	} else {
		/* 3 blocks per 51 multiframe */
		return 3;
	}
}

/* this ignores any possible paging combining! */
function f_pch_block_rate_est(boolean combined_ccch, integer bs_ag_blks_res) return float {
	var integer ccch_per_mframe := f_ccch_blocks_per_mframe(combined_ccch);
	var integer pch_per_mframe := ccch_per_mframe - bs_ag_blks_res;
	return GSM51_MFRAMES_PER_SEC * int2float(pch_per_mframe);
}

/* this ignores any possible imm.ass combining! */
function f_agch_block_rate_est(boolean combined_ccch, integer bs_ag_blks_res) return float {
	var integer ccch_per_mframe := f_ccch_blocks_per_mframe(combined_ccch);
	return GSM51_MFRAMES_PER_SEC * int2float(bs_ag_blks_res);
}

/* compute TC as per 45.002 6.3.1.3 */
function f_gsm_compute_tc(integer fn) return integer {
	return (fn / 51) mod 8;
}


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