module RUA_Emulation {

/* RUA_Emulation runs on top of Iuh_Emulation. It multiplexes/demultiplexes
 * the individuao connections, so there can be separate TTCN-3 components
 * handling each of the connections (one connection per UE).
 *
 * The RUA_Emulation.main() function processes RUA messages from the Iuh stack
 * via the RUA_PT, and dispatches them to the per-connection components.
 *
 * Outbound RUA connections are initiated by sending a FIXME primitive to the
 * RUA_Emulation component.
 *
 * For each new inbound connection, the RuaOps.create_cb() is called.  It can create
 * or resolve a TTCN-3 component, and returns a component reference to which that inbound
 * connection is routed/dispatched.
 *
 * If a pre-existing component wants to register to handle future inbound connection,
 * it can do so by registering an "expect" with the expected RANAP payload.

 * (C) 2022 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 General_Types all;
import from Osmocom_Types all;

import from Iuh_Emulation all;

import from RUA_Templates all;
//import from RUA_Constants all;
import from RUA_PDU_Descriptions all;
import from RUA_IEs all;

import from RANAP_PDU_Descriptions all;
//import from RANAP_Constants all;
import from RANAP_IEs all;
import from RANAP_Types all;
import from RANAP_Templates all;

modulepar {
	integer mp_max_context_id := hex2int('FFFFFF'H);
}


/* General "base class" component definition, of which specific implementations
 * derive themselves by means of the "extends" feature */
type component RUA_ConnHdlr {
	port RUA_Conn_PT RUA;
}

/* port between individual per-connection components and this dispatcher */
type port RUA_Conn_PT message {
	inout RANAP_PDU,
	      RUA_Conn_Req,
	      RUA_Disc_Req,
	      RUA_Disc_Ind;
} with { extension "internal" };

type record RUA_Conn_Req {
	boolean ps_domain,
	RANAP_PDU ranap
};

type record RUA_Disc_Req {
	RANAP_PDU ranap,
	RUA_IEs.Cause cause
};

type record RUA_Disc_Ind {
	RUA_IEs.Cause cause
};

type bitstring ContextId length(24); // with { variant "FIELDLENGTH(24)" };

/* represents a single RANAP connection over RUA */
type record ConnectionData {
	RUA_ConnHdlr	comp_ref,
	RUA_IEs.CN_DomainIndicator domain,
	integer		context_id
}

type component RUA_Emulation_CT {
	/* port to the bottom side (Iuh) */
	port RUA_PT RUA;

	/* ports to the upper side (per-connection components) */
	port RUA_Conn_PT CLIENT;

	/* use 16 as this is also the number of SCCP connections that SCCP_Emulation can handle */
	var ConnectionData ConnectionTable[16];

	/* pending expected incoming connections */
	//var ExpectData ExpectTable[8];

	/* tables for mapping inbound unitdata (like paging) */
	//var ImsiMapping ImsiTable[16];

	/* procedure based port to register for incoming connections */
	//port RUA_PROC_PT PROC;

	var charstring g_rua_id;
	var RuaOps g_rua_ops;
}

type function RanapCreateCallback(ContextId context_id, RUA_IEs.CN_DomainIndicator domain, charstring id)
runs on RUA_Emulation_CT return RUA_ConnHdlr;

type function RanapUnitdataCallback(RANAP_PDU ranap)
runs on RUA_Emulation_CT return template RANAP_PDU;

type record RuaOps {
	RanapCreateCallback create_cb optional,
	RanapUnitdataCallback unitdata_cb optional
	//boolean deode_dtap
	//boolean role_ms
};

private function f_context_id_known(ContextId context_id)
runs on RUA_Emulation_CT return boolean {
	var integer i;
	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ConnectionTable[i].context_id == bit2int(context_id)){
			return true;
		}
	}
	return false;
}

private function f_comp_known(RUA_ConnHdlr client)
runs on RUA_Emulation_CT return boolean {
	var integer i;
	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ConnectionTable[i].comp_ref == client) {
			return true;
		}
	}
	return false;
}

/* resolve connection ID by component reference */
private function f_context_id_by_comp(RUA_ConnHdlr client)
runs on RUA_Emulation_CT return ContextId {
	for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ConnectionTable[i].comp_ref == client) {
			return int2bit(ConnectionTable[i].context_id, 24);
		}
	}
	setverdict(fail, "RAN Connection table not found by component ", client);
	mtc.stop;
}

/* resolve ConnectionTable index component reference */
private function f_idx_by_comp(RUA_ConnHdlr client)
runs on RUA_Emulation_CT return integer {
	for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ConnectionTable[i].comp_ref == client) {
			return i;
		}
	}
	setverdict(fail, "RAN Connection table not found by component ", client);
	mtc.stop;
}

private function f_gen_context_id()
runs on RUA_Emulation_CT return ContextId {
	var ContextId context_id;

	do {
		context_id := int2bit(float2int(rnd()*int2float(mp_max_context_id)), 24);
	} while (f_context_id_known(context_id) == true);

	return context_id;
}

private function f_conn_table_init()
runs on RUA_Emulation_CT {
	for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
		ConnectionTable[i].comp_ref := null;
		ConnectionTable[i].context_id := -1;
	}
/*
	for (var integer i := 0; i < sizeof(ImsiTable); i := i+1) {
		ImsiTable[i].comp_ref := null;
		ImsiTable[i].imsi := omit;
		ImsiTable[i].tmsi := 'FFFFFFFF'O;
	}
*/
}

private function f_conn_table_add(RUA_ConnHdlr comp_ref, RUA_IEs.CN_DomainIndicator domain, ContextId context_id)
runs on RUA_Emulation_CT {
	var integer int_context_id := bit2int(context_id);
	for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ConnectionTable[i].context_id == -1) {
			ConnectionTable[i].comp_ref := comp_ref;
			ConnectionTable[i].domain := domain;
			ConnectionTable[i].context_id := int_context_id;
			log("Added conn table entry ", i, comp_ref, int_context_id);
			return;
		}
	}
	testcase.stop("RUA Connection table full!");
}

private function f_conn_table_del(ContextId context_id)
runs on RUA_Emulation_CT {
	var integer int_context_id := bit2int(context_id);
	for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ConnectionTable[i].context_id == int_context_id) {
			log("Deleted conn table entry ", i,
			    ConnectionTable[i].comp_ref, int_context_id);
			ConnectionTable[i].context_id := -1;
			return
		}
	}
	setverdict(fail, "RUA Connection table attempt to delete non-existant ", int_context_id);
	mtc.stop;
}


/* resolve component reference by connection ID */
private function f_comp_by_context_id(ContextId context_id)
runs on RUA_Emulation_CT return RUA_ConnHdlr {
	var integer int_context_id := bit2int(context_id);
	for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ConnectionTable[i].context_id == int_context_id) {
			return ConnectionTable[i].comp_ref;
		}
	}
	setverdict(fail, "RUA Connection table not found by RUA Context ID ", int_context_id);
	mtc.stop;
}

private function CommonRanapUnitdataCallback(RANAP_PDU ranap)
runs on RUA_Emulation_CT return template RANAP_PDU {
	/* TODO: paging */
	return g_rua_ops.unitdata_cb.apply(ranap);
}

private function f_handle_userData_RANAP(RUA_ConnHdlr client, RANAP_PDU ranap)
runs on RUA_Emulation_CT {
	/* TODO: L3 decoding, if requested */
	CLIENT.send(ranap) to client;
}


private altstep as_reset_ack() runs on RUA_Emulation_CT {
	var RUA_PDU rua_clt;
	[] RUA.receive(tr_RUA_ConnectionlessTransfer(decmatch tr_RANAP_Reset)) -> value rua_clt {
		var RANAP_PDU rx := dec_RANAP_PDU(rua_clt.initiatingMessage.value_.connectionlessTransfer.protocolIEs[0].value_.rANAP_Message);
		var RANAP_IEs.CN_DomainIndicator dom;
		dom := rx.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
		RUA.send(ts_RUA_ConnectionlessTransfer(enc_RANAP_PDU(valueof(ts_RANAP_ResetAck(dom)))));
	}
}

private altstep as_main_rua() runs on RUA_Emulation_CT {
	var RANAP_PDU ranap;
	var RUA_PDU rua;
	var octetstring ranap_enc;
	var ContextId context_id;
	var RUA_IEs.CN_DomainIndicator domain_ind;
	var RUA_ConnHdlr vc_conn;
	var RUA_Conn_Req creq;
	var RUA_Disc_Req dreq;
	var RUA_IEs.Cause cause;

	/* RUA -> Client: UNIT-DATA (connectionless RUA) from CN */
	[] RUA.receive(tr_RUA_ConnectionlessTransfer) -> value rua {
		ranap := dec_RANAP_PDU(rua.initiatingMessage.value_.connectionlessTransfer.protocolIEs[0].value_.rANAP_Message);
		var template RANAP_PDU resp;
		resp := CommonRanapUnitdataCallback(ranap);
		if (isvalue(resp)) {
			RUA.send(ts_RUA_ConnectionlessTransfer(enc_RANAP_PDU(valueof(resp))));
		}
	}

	/* RUA -> Client: new connection from CN */
	[] RUA.receive(tr_RUA_Connect) -> value rua {
		domain_ind := rua.initiatingMessage.value_.connect_.protocolIEs[0].value_.cN_DomainIndicator;
		context_id := rua.initiatingMessage.value_.connect_.protocolIEs[1].value_.context_ID;
		ranap_enc := rua.initiatingMessage.value_.connect_.protocolIEs[3].value_.rANAP_Message;
		ranap := dec_RANAP_PDU(ranap_enc);
		vc_conn := g_rua_ops.create_cb.apply(context_id, domain_ind, g_rua_id);
		/* store mapping between client components and RUA contextId */
		f_conn_table_add(vc_conn, domain_ind, context_id);
		/* TODO: notify user about incoming connection? */
		/* handle user payload */
		f_handle_userData_RANAP(vc_conn, ranap);
	}

	/* RUA -> Client: connection-oriented data in existing connection */
	[] RUA.receive(tr_RUA_DirectTransfer) -> value rua {
		context_id := rua.initiatingMessage.value_.directTransfer.protocolIEs[1].value_.context_ID;
		vc_conn := f_comp_by_context_id(context_id);
		ranap_enc := rua.initiatingMessage.value_.directTransfer.protocolIEs[2].value_.rANAP_Message;
		f_handle_userData_RANAP(vc_conn, dec_RANAP_PDU(ranap_enc));
	}

	/* RUA -> Client: disconnect of an existing connection */
	[] RUA.receive(tr_RUA_Disconnect_opt_ranap) -> value rua {
		cause := rua.initiatingMessage.value_.disconnect_.protocolIEs[2].value_.cause;
		context_id := rua.initiatingMessage.value_.disconnect_.protocolIEs[1].value_.context_ID;
		vc_conn := f_comp_by_context_id(context_id);
		/* send contained RANAP message to user */
		if (lengthof(rua.initiatingMessage.value_.disconnect_.protocolIEs) > 3) {
			ranap_enc := rua.initiatingMessage.value_.disconnect_.protocolIEs[3].value_.rANAP_Message;
			f_handle_userData_RANAP(vc_conn, dec_RANAP_PDU(ranap_enc));
		}
		/* notify user of disconnect */
		if (CLIENT.checkstate("Connected")) {
			CLIENT.send(RUA_Disc_Ind:{cause});
		}
		f_conn_table_del(context_id);
	}

	/* RANAP from client through an existing RANAP connection */
	[] CLIENT.receive(RANAP_PDU:?) -> value ranap sender vc_conn {
		var integer idx := f_idx_by_comp(vc_conn);
		context_id := int2bit(ConnectionTable[idx].context_id, 24);
		domain_ind := ConnectionTable[idx].domain;
		RUA.send(ts_RUA_DirectTransfer(domain_ind, context_id, enc_RANAP_PDU(ranap)));
	}

	/* Disconnect request from client */
	[] CLIENT.receive(RUA_Disc_Req:?) -> value dreq sender vc_conn {
		var octetstring enc_ranap := enc_RANAP_PDU(dreq.ranap);
		var integer idx := f_idx_by_comp(vc_conn);
		context_id := int2bit(ConnectionTable[idx].context_id, 24);
		domain_ind := ConnectionTable[idx].domain;
		RUA.send(ts_RUA_Disconnect(domain_ind, context_id, dreq.cause, enc_ranap));
		f_conn_table_del(context_id);
	}

	/* RANAP from client, for a new RANAP connection */
	[] CLIENT.receive(RUA_Conn_Req:?) -> value creq sender vc_conn {
		var octetstring enc_ranap := enc_RANAP_PDU(creq.ranap);

		if (f_comp_known(vc_conn) == false) {
			/* unknown client, create new connection */
			context_id := f_gen_context_id();
			if (creq.ps_domain) {
				domain_ind := ps_domain;
			} else {
				domain_ind := cs_domain;
			}

			f_conn_table_add(vc_conn, domain_ind, context_id);
			RUA.send(ts_RUA_Connect(domain_ind, context_id, normal_call, enc_ranap));
		} else {
			/* known client, send via existing component */
			context_id := f_context_id_by_comp(vc_conn);
			RUA.send(ts_RUA_DirectTransfer(domain_ind, context_id, enc_ranap));
		}
	}

}



function f_ranap_reset(RANAP_IEs.CN_DomainIndicator dom) runs on RUA_Emulation_CT {
	timer T := 5.0;

	var RANAP_PDU tx := valueof(ts_RANAP_Reset(ts_RanapCause_om_intervention,dom));
	RUA.send(ts_RUA_ConnectionlessTransfer(enc_RANAP_PDU(tx)));
	T.start;
	alt {
	[] RUA.receive(tr_RUA_ConnectionlessTransfer(decmatch tr_RANAP_ResetAck)) {
		log("RUA-RANAP: Received RESET-ACK in response to RESET, we're reay to go!");
		}
	[] as_reset_ack();
	[] RUA.receive { repeat; }
	[] T.timeout {
		setverdict(fail, "RUA-RANAP: Timeout waiting for RESET-ACK after sending RESET");
		mtc.stop;
		}
	}
}

function main(RuaOps ops, charstring id) runs on RUA_Emulation_CT {
	g_rua_id := id;
	g_rua_ops := ops;
	f_conn_table_init();
	//f_expect_table_init();

	while (true) {
		alt {
		[] as_main_rua();

		/*
		[] PROC.getcall(RUA_Register:{?,?}) -> param(l3_info, vc_hdlr) {
			f_create_expect(l3_info, vc_hdlr);
			PROC.reply(RUA_register:{l3_info, vc_hdlr}) to vc_hdlr;
			}
		*/
		}
	}
}


}
