module GPRS_TBF {

/* GPRS TBF Routines, intended as minimal MS-Side GPRS implementation
 *
 * (C) 2018 by 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
 */

import from GSM_Types all;
import from Osmocom_Types all;
import from General_Types all;
import from RLCMAC_CSN1_Types all;
import from RLCMAC_Types all;
import from RLCMAC_Templates all;
import from LLC_Types all;
import from GPRS_Context all;

private const integer RLC_GPRS_SNS := 128;
private const integer RLC_GPRS_WS := 64;
private const integer RLC_EGPRS_MIN_WS := 64;
private const integer RLC_EGPRS_MAX_WS := 1024;
private const integer RLC_EGPRS_SNS := 2048;
private const integer RLC_EGPRS_MAX_BSN_DELTA := 512;
private const integer RLC_MAX_SNS := RLC_EGPRS_SNS;
private const integer RLC_MAX_WS := RLC_EGPRS_MAX_WS;
private const integer RLC_MAX_LEN := 74 /* MCS-9 data unit */

private const integer sns_half := (RLC_MAX_SNS / 2);
private const integer mod_sns_half := (RLC_MAX_SNS / 2) - 1;


/***********************************************************************
 * Uplink TBF handling
 ***********************************************************************/

/* input parameters into TBF (mostly mode/cs + LLC PDUs */
type record UlTbfPars {
	/* Acknowledged mode (true) or unacknowledged (false) */
	boolean			ack_mode,
	/* Coding Scheme for transmission, determines block size */
	GprsCodingScheme	initial_cs,
	/* list of abstract/decoded LLC PDUs */
	record of PDU_LLC	llc_pdus optional,
	/* possibly computed: list of encoded LLC PDUs */
	record of octetstring 	llc_pdus_enc
}

type record RlcEndpointTx {
	/* send state variable V(S) (9.1.1): 0 .. SNS-1 */
	integer			v_s,
	/* acknowledge state variable V(A) (9.1.2): BSN value of oldest RLC data block that has not
	 * been positively acknowledged by peer. */
	integer			v_a,
	/* acknowledge state array V(B) (9.1.3) */
	bitstring		v_b
}
private function f_RlcEndpointTx_init(inout RlcEndpointTx ep) {
	ep.v_s := 0;
	ep.v_a := 0;
	ep.v_b := int2bit(0, 128); /* FIXME: EGPRS 2048 bits length */
}

type record UlTbfState {
	/* "const" input state with TBF Data */
	UlTbfPars		tbf,
	uint8_t			num_ts,

	RlcEndpointTx		et,

	integer			tfi,
	/* total length of all encoded LLC PDUs */
	integer			llc_pdu_totlen,
	/* index of current/next PDU in llc_pdus_enc */
	integer			cur_pdu,
	/* byte offset into current/next PDU; next byte to transmit */
	integer			cur_index,
	/* block sequence number of next block within TBF */
	integer			bsn_p,
	/* total number of bytes remaining in TBF */
	integer			total_bytes_remain,

	/* list of already-sent RLC/MAC Blocks */
	record of RlcmacUlBlock	rlc_sent
}

function f_UlTbfState_init(inout UlTbfState us, in UlTbfPars utpars) {
	var RlcmacUlBlock blk;

	us.tbf := utpars;
	us.num_ts := 1;

	f_RlcEndpointTx_init(us.et);

	us.tfi := 0;	/* FIXME */
	us.cur_pdu := 0;
	us.cur_index := 0;
	us.bsn_p := 0;
	us.total_bytes_remain := 0;
	us.rlc_sent := {};

	/* encode all LLC PDUs from their abstract type to octetstring */
	us.cur_pdu := 0;	/* currently processed PDU */
	us.cur_index := 0;	/* next to-be transmitted index */
	if (ispresent(us.tbf.llc_pdus)) {
		us.tbf.llc_pdus_enc := {};
		us.llc_pdu_totlen := 0;
		for (var integer i := 0; i < sizeof(us.tbf.llc_pdus); i := i+1) {
			var octetstring cur_enc := enc_PDU_LLC(us.tbf.llc_pdus[i]);
			us.tbf.llc_pdus_enc := us.tbf.llc_pdus_enc & { cur_enc };
			us.llc_pdu_totlen := us.llc_pdu_totlen + lengthof(cur_enc);
		}
		us.total_bytes_remain := us.llc_pdu_totlen;
	}
}

private function f_UlTbf_ack_one_block(inout UlTbfState us, integer n) {
	/* compute index into v_b */
	var integer idx := n - us.et.v_a;
	if (idx < 0 or idx > lengthof(us.et.v_b)) {
		setverdict(fail, "UlTbf: Cannot ACK ", n, " while V(A) is ", us.et.v_a);
		mtc.stop;
	}
	/* set the bit in the acknowledge state array */
	us.et.v_b[idx] := '1'B;
}

/* check if V(B) contains '1' at lower end: if yes, advance V(A) and shift V(B) */
private function f_UlTbf_check_advance_v_a(inout UlTbfState us) {
	log("FIXME: Implement this");
}

/* copy 'len' number of bytes from current pending LLC PDU */
private function f_copy_from_llc(inout UlTbfState us, integer len) return octetstring
{
	var integer pdu_len := lengthof(us.tbf.llc_pdus_enc[us.cur_pdu])
	var octetstring ret;

	ret := substr(us.tbf.llc_pdus_enc[us.cur_pdu], us.cur_index, len);

	us.cur_index := us.cur_index + len;
	us.total_bytes_remain := us.total_bytes_remain - len;

	/* if we completed this PDU, move on to the next, resetting the index */
	if (us.cur_index >= pdu_len) {
		us.cur_pdu := us.cur_pdu +1;
		us.cur_index := 0;
		log("copy_from_llc (incrementing pdu)");
	}

	return ret;
}

/* generate one LlcBlock (maximum size 'max_len') */
private function f_ul_tbf_pull_one(out LlcBlock ret, inout LlcBlockHdr prev_hdr,
				   inout UlTbfState us, integer max_len,
				   boolean is_final) return boolean
{
	/* if we've already pulled all data from all LLC PDUs: nothing to do */
	if (us.cur_pdu >= sizeof(us.tbf.llc_pdus_enc)) {
		log("pull_one: No more data", us);
		return false;
	}

	var integer pdu_len := lengthof(us.tbf.llc_pdus_enc[us.cur_pdu])
	var integer cur_llc_remain_len := pdu_len - us.cur_index;
	var integer len;
	var LlcBlock lb;

	if (us.cur_index == 0) {
		/* start of a new LLC PDU */
		prev_hdr.more := true;
	}

	if (cur_llc_remain_len > max_len) {
		log("Chunk with length ", cur_llc_remain_len, " larger than space (",
			max_len, ") left in block");
		len := max_len;
		lb := {
			hdr := omit,
			payload := f_copy_from_llc(us, len)
		}
	} else if (cur_llc_remain_len == max_len and is_final) {
		/* final RLC block of TBF and LLC remainder fits exactly */
		len := max_len;
		lb := {
			hdr := omit,
			payload := f_copy_from_llc(us, len)
		}
		prev_hdr.e := true;
	} else if (cur_llc_remain_len == max_len) {
		/* LLC remaineder would fit exactly -> "singular case" with L=0 */
		len := max_len - 1;
		lb := {
			hdr := {
				length_ind := 0,
				more := false,
				e := true
			},
			payload := f_copy_from_llc(us, len)
		}
		prev_hdr.e := false;
	} else {
		/* normal case: cur_llc_remain_len < max_len */
		len := cur_llc_remain_len;
		lb := {
			hdr := {
				length_ind := len,
				more := false,
				e := true
			},
			payload := f_copy_from_llc(us, len)
		}
		prev_hdr.e := false;
	}
	ret := lb;
	return true;
}

/* return encoded size of one given LlcBlock */
private function f_LlcBlock_enc_len(LlcBlock blk) return integer {
	if (isvalue(blk.hdr)) {
		return 1 + lengthof(blk.payload);
	} else {
		return lengthof(blk.payload);
	}
}

/* return encoded size of given record of LlcBlock */
private function f_LlcBlocks_enc_len(LlcBlocks blks) return integer {
	var integer sum := 0;
	for (var integer i := 0; i < sizeof(blks); i := i+1) {
		sum := sum + f_LlcBlock_enc_len(blks[i]);
	}
	return sum;
}

private function f_ul_tbf_pull_multi(out LlcBlocks ret, inout UlTbfState us, integer max_len,
				     boolean is_final) return boolean
{
	var integer space_left;
	var boolean rc;
	ret := {};

	/* loop as long as we have pending LLC data and space left in the current block... */
	for (space_left := max_len; space_left > 0; space_left := max_len - f_LlcBlocks_enc_len(ret)) {
		var LlcBlock lb;
		var integer ret_size := sizeof(ret);
		if (ret_size > 0) {
			rc := f_ul_tbf_pull_one(lb, ret[ret_size-1].hdr, us, space_left, is_final);
		} else {
			var LlcBlockHdr dummy_hdr;
			rc := f_ul_tbf_pull_one(lb, dummy_hdr, us, space_left, is_final);
		}
		if (rc == false) {
			/* we couldn't fill the full RLC block, insufficient LLC Data */
			if (sizeof(ret) == 0) {
				/* we couldn't obtain any LlcBlocks at all */
				return false;
			} else {
				/* we have some LlcBlocks from earlier iterations */
				return true;
			}
		}
		ret := ret & {lb};
	}
	return true;
}

/* Determine 'K' value for given CS (TS 44.060 9.3.1.1) */
private function f_k_for_cs(GprsCodingScheme cs) return integer {
	/* FIXME: EGPRS */
	return 1;
}

/* TS 44.060 9.3.1.1 */
private function f_calc_cv(integer nbc, integer bsn_p, integer nts, GprsCodingScheme cs,
			   integer bs_cv_max) return integer {
	var integer dividend := nbc - bsn_p - 1;
	var integer k := f_k_for_cs(cs);
	var integer divisor := nts * k;
	var integer x := f_div_round_up(dividend, divisor);
	if (x <= bs_cv_max) {
		return x;
	} else {
		return 15;
	}
}

private function f_rlcmac_hdr_size(boolean tlli_needed) return integer {
	var integer ret := 2;
	if (tlli_needed) {
		ret := ret + 4;
	}
	return ret;
}

/* determine countdown value based on remaining length pending */
private function f_ul_tbf_get_cv(inout UlTbfState us, GprsCodingScheme cs, boolean tlli_needed)
return integer {
	var integer hdr_size := f_rlcmac_hdr_size(tlli_needed); /* FIXME: PFI, ... */
	var integer blk_len_net := f_gprs_blocksize(cs) - hdr_size;
	var integer num_remain := f_div_round_up(us.total_bytes_remain, blk_len_net);
	var integer cv := f_calc_cv(num_remain + sizeof(us.rlc_sent), us.bsn_p, us.num_ts, us.tbf.initial_cs, 14 /* FIXME */);
	return cv;
}


function f_ul_tbf_get_next_block(out RlcmacUlBlock blk, inout UlTbfState us, inout MmContext mmctx,
				 boolean tlli_needed := false) return boolean {
	var integer hdr_size := f_rlcmac_hdr_size(tlli_needed); /* FIXME: TLLI, PFI, ... */
	var integer len_remain := f_gprs_blocksize(us.tbf.initial_cs) - hdr_size;
	var octetstring payload;
	var integer cv;
	var LlcBlocks llc_blocks;

	cv := f_ul_tbf_get_cv(us, us.tbf.initial_cs, tlli_needed);
	/* potentially get multiple payload chunks of multiple LLC PDUs */
	if (f_ul_tbf_pull_multi(llc_blocks, us, len_remain, false) == false) {
		return false;
	}

	/* include TLLI when needed */
	if (tlli_needed) {
		blk := valueof(t_RLCMAC_UL_DATA_TLLI(us.tfi, cv, us.et.v_s,
						llc_blocks, false, mmctx.tlli));
	} else {
		blk := valueof(t_RLCMAC_UL_DATA(us.tfi, cv, us.et.v_s, llc_blocks, false));
	}

	/* Increment Block Sequence Number */
	us.bsn_p := us.bsn_p + 1;
	us.et.v_s := us.bsn_p mod 128; /* FIXME: EGPRS SNS: 2048 */

	/* append to list of sent blocks */
	us.rlc_sent := us.rlc_sent & { blk };

	return true;
}

function f_ul_tbf_process_acknack(inout UlTbfState us, RlcmacDlCtrlBlock db) {
	if (ispresent(db.payload.u.ul_ack_nack.gprs)) {
		var UlAckNackGprs uan_gprs := db.payload.u.ul_ack_nack.gprs;
		if (ispresent(uan_gprs.cont_res_tlli)) {
			/* FIXME: check for contention resolution */
		}
		var integer i;
		/* iterate over received bitmap, ACK each block in our TBF state */
		for (i := lengthof(uan_gprs.ack_nack_desc.receive_block_bitmap)-1; i >= 0; i := i-1) {
			if (uan_gprs.ack_nack_desc.receive_block_bitmap[i] == '1'B) {
				var integer seq := uan_gprs.ack_nack_desc.starting_seq_nr + i;
				f_UlTbf_ack_one_block(us, seq);
			}
		}
		f_UlTbf_check_advance_v_a(us);
	}
}

/***********************************************************************
 * Downlink TBF handling
 ***********************************************************************/

type record RlcEndpointRx {
	/* receive state variable V(R) (9.1.5): BSN one higher than highest BSN yet received (mod SNS) */
	integer			v_r,
	/* receive window state variable V(Q) (9.1.6): Lowest BSN not yet received (mod SNS) */
	integer			v_q,
	/* receive state array V(N) (9.1.7) */
	bitstring		v_n
}

private function f_RlcEndpointRx_init(inout RlcEndpointRx ep) {
	ep.v_r := 0;
	ep.v_q := 0;
	ep.v_n := int2bit(0, 128); /* FIXME: EGPRS 2048 bits length */
}

type record DlTbfPars {
	/* Acknowledged mode (true) or unacknowledged (false) */
	boolean			ack_mode,
	/* Coding Scheme for transmission, determines block size */
	GprsCodingScheme	initial_cs,
	/* Sequence Number Space */
	integer			sns,
	/* Window Size */
	integer			ws
}

type record DlTbfState {
	/* "const" input state with TBF Data */
	DlTbfPars		tbf,
	uint8_t			num_ts,

	RlcEndpointRx		er,

	integer			tfi,

	/* list of abstract/decoded RLC PDUs */
	record of RlcmacDlBlock	rlc_received
}

function f_dl_tbf_mod_sns(DlTbfState ds, integer val) return integer
{
	return (val mod ds.tbf.sns);
}

function f_dl_tbf_is_in_window(integer bsn) return boolean {
	setverdict(fail, "pleaes implement me");
	mtc.stop;
}

function f_dl_tbf_is_received(inout DlTbfState ds, integer bsn) return boolean {
	var integer offset_v_r;

	if (not f_dl_tbf_is_in_window(bsn)) {
		return false;
	}

	/* offset to the end of the received window */
	offset_v_r := f_dl_tbf_mod_sns(ds, ds.er.v_r - 1 - bsn);
	if (not (offset_v_r < ds.tbf.ws)) {
		return false;
	}

	if (ds.er.v_n[bsn mod sns_half] == '1'B) {
		return true;
	}

	return false;
}

function f_dl_tbf_mark_received(inout DlTbfState ds, integer bsn) {
	ds.er.v_n[bsn mod sns_half] := '1'B;
	f_dl_tbf_raise_v_r(ds, bsn);
}

/* Raise V(Q) if possible */
function f_dl_tbf_raise_v_q(inout DlTbfState ds, integer bsn) return integer {
	var integer count := 0;
	while (ds.er.v_q != ds.er.v_r) {
		var integer v_q_old := ds.er.v_q;
		if (not f_dl_tbf_is_received(ds, v_q_old)) {
			break;
		}
		ds.er.v_q := f_dl_tbf_mod_sns(ds, ds.er.v_q + 1)
		log("RLCMAC: Taking block ", v_q_old, " out, raising V(Q) to ", ds.er.v_q);
		count := count+1;
	}
	return count;
}

function f_dl_tbf_raise_v_r(inout DlTbfState ds, integer bsn) {
	var integer offset_v_r := f_dl_tbf_mod_sns(ds, bsn + 1 - ds.er.v_r);
	if (offset_v_r < (ds.tbf.sns / 2)) {
		for (var integer i := offset_v_r; i > 0; i := i-1) {
			/* mark as missing */
			ds.er.v_n[bsn mod sns_half] := '0'B;
			//raise_v_r_to(1);
		}
		log("RLCMAC: Raising V(R) to ", ds.er.v_r);
	}
}

/* process the actual data and update TbfState */
function f_dl_tbf_process_dl_data(inout DlTbfState ds, RlcmacDlDataBlock db) {
	var integer bsn := db.mac_hdr.hdr_ext.bsn;
	if (db.mac_hdr.hdr_ext.tfi != ds.tfi) {
		setverdict(fail, "Unexpected TFI of DL Data Block ", db);
		mtc.stop;
	}
	f_dl_tbf_mark_received(ds, bsn);
	if (ds.tbf.ack_mode) {
		/* In RLC acknowledged mode, the receive window is defined by the receive window
		 * state variable V(Q) in the following inequality[ V(Q) ≤ BSN < V(Q)+ WS ] modulo
		 * SNS */
		if (bsn < ds.er.v_q or bsn > ds.er.v_q + ds.tbf.ws) {
			setverdict(fail, "Unexpected BSN outside of window ", bsn);
			mtc.stop;
		}

		/* In RLC acknowledged mode, the value of V(Q) shall be updated when the RLC
		 * receiver receives the RLC data block whose BSN is equal to V(Q). The value of
		 * V(Q) shall then be set to the BSN value of the next RLC data block in the receive
		 * window (modulo SNS) that has not yet been received, or it shall be set to V(R) if
		 * all RLC data blocks in the receive window have been received */
		f_dl_tbf_mark_received(ds, bsn);
	} else {
		/* In RLC unacknowledged mode, if [V(R) - V(Q)] modulo SNS > WS after updating V(R),
		 * then V(Q) is set to [V(R) - WS] modulo SNS. */
		/* FIXME */
	}

}



}
