module IuUP_Emulation {

/* IuUP emulation, uses the encoding/decoding from IuUP_Types.
 *
 * rather than running in a separate component with related primitives,
 * we just implement a set of functions and data types which can be used
 * by other code (such as an RTP endpoint) to implement IuUP support.
 *
 * (C) 2017 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 Osmocom_Types all;
import from IuUP_Types all;


type record IuUP_RabFlowCombination {
	IuUP_RFCI rfci,
	/* number of bits per sub-flow */
	RecOfU8	sub_flow_bits,
	/* IPTI value in number of ITIs for the corresponding RFCI */
	uint8_t ipti
};

template (value) IuUP_RabFlowCombination t_IuUP_RFC(IuUP_RFCI rfci, RecOfU8 subflow_bits, uint8_t ipti) := {
	rfci := rfci,
	sub_flow_bits := subflow_bits,
	ipti := ipti
}

template (value) IuUP_RabFlowCombination t_IuUP_RFC_AMR_12_2(IuUP_RFCI rfci) := t_IuUP_RFC(rfci, {81, 103, 60}, 1);
template (value) IuUP_RabFlowCombination t_IuUP_RFC_AMR_SID(IuUP_RFCI rfci) := t_IuUP_RFC(rfci, {34, 0, 0}, 7);

type record IuUP_Config {
	/* actively send INIT (true) or only passively respond (false) */
	boolean active_init,
	boolean data_pdu_type_0,
	/* RAB Flow Combinations */
	record of IuUP_RabFlowCombination rab_flow_combs
};

type enumerated IuUP_Em_State {
	ST_INIT,
	ST_DATA_TRANSFER_READY
};



type record IuUP_Entity {
	IuUP_Config cfg,
	IuUP_Em_State state,
	IuUP_FrameNr tx_next_frame_nr,
	IuUP_FrameNr rx_last_frame_nr optional,
	IuUP_PDU pending_tx_pdu optional
};

template (value) IuUP_Entity t_IuUP_Entity(boolean act_init) := {
	cfg := {
		active_init := act_init,
		data_pdu_type_0 := true,
		rab_flow_combs := { t_IuUP_RFC_AMR_12_2(0), t_IuUP_RFC_AMR_SID(1) }
	},
	state := ST_INIT,
	tx_next_frame_nr := 0,
	rx_last_frame_nr := omit,
	pending_tx_pdu := omit
}


function f_IuUP_Em_rx_decaps(inout IuUP_Entity st, octetstring inp) return octetstring {
	var IuUP_PDU pdu := dec_IuUP_PDU(inp);
	if (ischosen(pdu.type_0)) {
		if (st.cfg.data_pdu_type_0) {
			/* FIXME: check header / CRC */
			st.rx_last_frame_nr := pdu.type_0.frame_nr;
			return pdu.type_0.payload;
		} else {
			setverdict(fail, "PDU Type 0 received but 1 configured");
			mtc.stop;
		}
	} else if (ischosen(pdu.type_1)) {
		if (st.cfg.data_pdu_type_0 == false) {
			/* FIXME: check header / CRC */
			st.rx_last_frame_nr := pdu.type_1.frame_nr;
			return pdu.type_1.payload;
		} else {
			setverdict(fail, "PDU Type 1 received but 0 configured");
			mtc.stop;
		}
	} else if (ischosen(pdu.type_14)) {
		if (match(pdu, tr_IuUP_INIT)) {
			if (st.cfg.active_init == true) {
				setverdict(fail, "INIT received in ACTIVE role");
				mtc.stop;
			} else {
				/* store an INIT_ACK to be transmitted later */
				st.pending_tx_pdu := valueof(ts_IuUP_INIT_ACK(pdu.type_14.frame_nr,
									pdu.type_14.iuup_version));
			}
		} else if (match(pdu, tr_IuUP_INIT_ACK)) {
			if (st.cfg.active_init == true) {
				log("IuUP INIT_ACK Received");
				st.state := ST_DATA_TRANSFER_READY;
			} else {
				setverdict(fail, "INIT_ACK received in PASSIVE role");
				mtc.stop;
			}
		}
		return ''O;
	} else {
		setverdict(fail, "Impossible IuUP PDU decoded from ", inp);
		mtc.stop;
	}
	self.stop;
}

function f_IuUP_Em_tx_encap(inout IuUP_Entity st, in octetstring payload) return octetstring {
	var IuUP_PDU pdu;
	select (st.state) {
		case (ST_INIT) {
			if (st.cfg.active_init) {
				/* send INIT */
				pdu := valueof(ts_IuUP_INIT('160051673C01270000820000001710000100'O));
			} else {
				/* wait for INIT */
				if (isvalue(st.pending_tx_pdu)) {
					/* we're waiting to transmit the INIT_ACK in response to an
					 * init (passive) */
					pdu := st.pending_tx_pdu;
					st.pending_tx_pdu := omit;
					st.state := ST_DATA_TRANSFER_READY;
				}
			}
		}
		case (ST_DATA_TRANSFER_READY) {
			if (st.cfg.data_pdu_type_0) {
				pdu := valueof(ts_IuUP_Type0(st.tx_next_frame_nr, 0, payload));
			} else {
				pdu := valueof(ts_IuUP_Type1(st.tx_next_frame_nr, 0, payload));
			}
			st.tx_next_frame_nr := st.tx_next_frame_nr + 1;
		}
	}
	if (isvalue(pdu)) {
		return f_enc_IuUP_PDU(pdu);
	} else {
		return ''O;
	}
}


}
