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_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;

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

}



}
