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.
 */


import from GSM_Types all;
import from Osmocom_Types all;
import from General_Types all;
import from RLCMAC_Types all;
import from RLCMAC_CSN1_Types 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;

	log("copy_from_llc: ", ret, " us: ", us);

	/* 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 */);
	log("CV=", cv, ", num_rmain=", num_remain, " from ", us);
	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 */
	}

}



}
