module BSSMAP_Emulation {

/* BSSMAP Emulation, runs on top of BSSAP_CodecPort.  It multiplexes/demultiplexes
 * the individual connections, so there can be separate TTCN-3 components handling
 * each of the connections.
 *
 * The BSSMAP_Emulation.main() function processes SCCP primitives from the SCCP
 * stack via the BSSAP_CodecPort, and dispatches them to the per-connection components.
 *
 * Outbound BSSAP/SCCP connections are initiated by sending a BSSAP_Conn_Req primitive
 * to the component running the BSSMAP_Emulation.main() function.
 *
 * For each new inbound connections, the BssmapOps.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 a future inbound connection, it can
 * do so by registering an "expect" with the expected Layer 3 (DTAP) payload.  This is e.g. useful
 * if you are simulating BTS + MSC, and first trigger a connection from BTS/RSL side in a
 * component which then subsequently should also handle the MSC emulation.
 *
 * Inbound Unit Data messages (such as are dispatched to the BssmapOps.unitdata_cb() callback,
 * which is registered with an argument to the main() function below.
 *
 * (C) 2017-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 General_Types all;
import from SCCP_Emulation all;
import from SCCPasp_Types all;
import from BSSAP_Types all;
import from BSSAP_CodecPort all;
import from BSSMAP_Templates all;
import from MGCP_Types all;
import from MGCP_Templates all;
import from IPA_Emulation all;
import from MobileL3_Types all;

/* General "base class" component definition, of which specific implementations
 * derive themselves by means of the "extends" feature */
type component BSSAP_ConnHdlr {
	/* port towards MSC Emulator core / SCCP connection dispatchar */
	port BSSAP_Conn_PT BSSAP;
	/* procedure based port to register for incoming connections */
	port BSSMAPEM_PROC_PT BSSAP_PROC;
}

/* Auxiliary primitive that can happen on the port between per-connection client and this dispatcher */
type enumerated BSSAP_Conn_Prim {
	/* SCCP tell us that connection was released */
	MSC_CONN_PRIM_DISC_IND,
	/* we tell SCCP to release connection */
	MSC_CONN_PRIM_DISC_REQ,
	/* Connection confirmed indication */
	MSC_CONN_PRIM_CONF_IND
}

type record BSSAP_Conn_Req {
	SCCP_PAR_Address	addr_peer,
	SCCP_PAR_Address	addr_own,
	PDU_BSSAP		bssap
}

/* similar to PDU_BSSAP with DTAP, but DTAP is already decoded! */
type record PDU_DTAP_MO {
	OCT1			dlci optional,
	PDU_ML3_MS_NW		dtap
}

/* similar to PDU_BSSAP with DTAP, but DTAP is already decoded! */
type record PDU_DTAP_MT {
	OCT1			dlci optional,
	PDU_ML3_NW_MS		dtap
}

template PDU_DTAP_MT ts_PDU_DTAP_MT(template PDU_ML3_NW_MS dtap, template OCT1 dlci := omit) := {
	dlci := dlci,
	dtap := dtap
}

template PDU_DTAP_MO ts_PDU_DTAP_MO(template PDU_ML3_MS_NW dtap, template OCT1 dlci := '00'O) := {
	dlci := dlci,
	dtap := dtap
}

template PDU_DTAP_MT tr_PDU_DTAP_MT(template PDU_ML3_NW_MS dtap, template OCT1 dlci := *) := {
	dlci := dlci,
	dtap := dtap
}

template PDU_DTAP_MO tr_PDU_DTAP_MO(template PDU_ML3_MS_NW dtap, template OCT1 dlci := *) := {
	dlci := dlci,
	dtap := dtap
}


/* port between individual per-connection components and this dispatcher */
type port BSSAP_Conn_PT message {
	inout PDU_BSSAP, PDU_DTAP_MO, PDU_DTAP_MT, BSSAP_Conn_Prim, BSSAP_Conn_Req, MgcpCommand, MgcpResponse;
} with { extension "internal" };


/* represents a single BSSAP connection over SCCP */
type record ConnectionData {
	/* reference to the instance of the per-connection component */
	BSSAP_ConnHdlr	comp_ref,
	integer		sccp_conn_id,
	/* most recent MGCP transaction ID (Used on MSC side) */
	MgcpTransId	mgcp_trans_id optional,
	/* CIC that has been used for voice of this channel (BSC side) */
	integer		cic optional
}

type component BSSMAP_Emulation_CT {
	/* SCCP port on the bottom side, using ASP primitives */
	port BSSAP_CODEC_PT BSSAP;
	/* BSSAP port to the per-connection clients */
	port BSSAP_Conn_PT CLIENT;
	/* MGCP port */
	port IPA_MGCP_PT MGCP;

	/* 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];
	/* procedure based port to register for incoming connections */
	port BSSMAPEM_PROC_PT PROC;

	var charstring g_bssmap_id;
	var integer g_next_e1_ts := 1;
	var BssmapOps g_bssmap_ops;
};

private function f_conn_id_known(integer sccp_conn_id)
runs on BSSMAP_Emulation_CT return boolean {
	var integer i;
	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ConnectionTable[i].sccp_conn_id == sccp_conn_id){
			return true;
		}
	}
	return false;
}

private function f_comp_known(BSSAP_ConnHdlr client)
runs on BSSMAP_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;
}

private function f_cic_known(integer cic)
runs on BSSMAP_Emulation_CT return boolean {
	var integer i;
	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ConnectionTable[i].cic == cic) {
			return true;
		}
	}
	return false;
}

/* resolve component reference by connection ID */
private function f_comp_by_conn_id(integer sccp_conn_id)
runs on BSSMAP_Emulation_CT return BSSAP_ConnHdlr {
	var integer i;
	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ConnectionTable[i].sccp_conn_id == sccp_conn_id) {
			return ConnectionTable[i].comp_ref;
		}
	}
	log("BSSMAP Connection table not found by SCCP Connection ID ", sccp_conn_id);
	setverdict(fail);
	self.stop;
}

/* resolve component reference by CIC */
private function f_comp_by_mgcp_tid(MgcpTransId tid)
runs on BSSMAP_Emulation_CT return BSSAP_ConnHdlr {
	var integer i;
	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ConnectionTable[i].mgcp_trans_id == tid) {
			return ConnectionTable[i].comp_ref;
		}
	}
	log("BSSMAP Connection table not found by MGCP Transaction ID ", tid);
	setverdict(fail);
	self.stop;
}

private function f_comp_store_mgcp_tid(BSSAP_ConnHdlr client, MgcpTransId tid)
runs on BSSMAP_Emulation_CT {
	var integer i;
	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ConnectionTable[i].comp_ref == client) {
			ConnectionTable[i].mgcp_trans_id := tid;
			return;
		}
	}
	log("BSSMAP Connection table not found by component ", client);
	setverdict(fail);
	self.stop;
}

private function f_comp_by_cic(integer cic)
runs on BSSMAP_Emulation_CT return BSSAP_ConnHdlr {
	var integer i;
	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ConnectionTable[i].cic == cic) {
			return ConnectionTable[i].comp_ref;
		}
	}
	log("BSSMAP Connection table not found by CIC ", cic);
	setverdict(fail);
	self.stop;
}

private function f_comp_store_cic(BSSAP_ConnHdlr client, integer cic)
runs on BSSMAP_Emulation_CT {
	var integer i;
	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ConnectionTable[i].comp_ref == client) {
			ConnectionTable[i].cic := cic;
			return;
		}
	}
	log("BSSMAP Connection table not found by component ", client);
	setverdict(fail);
}

/* resolve connection ID by component reference */
private function f_conn_id_by_comp(BSSAP_ConnHdlr client)
runs on BSSMAP_Emulation_CT return integer {
	for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ConnectionTable[i].comp_ref == client) {
			return ConnectionTable[i].sccp_conn_id;
		}
	}
	log("BSSMAP Connection table not found by component ", client);
	setverdict(fail);
	self.stop;
}

private function f_gen_conn_id()
runs on BSSMAP_Emulation_CT return integer {
	var integer conn_id;

	do {
		conn_id := float2int(rnd()*SCCP_Emulation.tsp_max_ConnectionId);
	} while (f_conn_id_known(conn_id) == true);

	return conn_id;
}

private function f_conn_table_init()
runs on BSSMAP_Emulation_CT {
	for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
		ConnectionTable[i].comp_ref := null;
		ConnectionTable[i].sccp_conn_id := -1;
		ConnectionTable[i].mgcp_trans_id := omit;
		ConnectionTable[i].cic := omit;
	}
}

private function f_conn_table_add(BSSAP_ConnHdlr comp_ref, integer sccp_conn_id)
runs on BSSMAP_Emulation_CT {
	for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ConnectionTable[i].sccp_conn_id == -1) {
			ConnectionTable[i].comp_ref := comp_ref;
			ConnectionTable[i].sccp_conn_id := sccp_conn_id;
			log("Added conn table entry ", i, comp_ref, sccp_conn_id);
			return;
		}
	}
	log("BSSMAP Connection table full!");
	setverdict(fail);
	self.stop;
}

private function f_conn_table_del(integer sccp_conn_id)
runs on BSSMAP_Emulation_CT {
	for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ConnectionTable[i].sccp_conn_id == sccp_conn_id) {
			log("Deleted conn table entry ", i,
			    ConnectionTable[i].comp_ref, sccp_conn_id);
			ConnectionTable[i].sccp_conn_id := -1;
			ConnectionTable[i].comp_ref := null;
			return
		}
	}
	log("BSSMAP Connection table attempt to delete non-existant ", sccp_conn_id);
	setverdict(fail);
	self.stop;
}

/* handle (optional) userData portion of various primitives and dispatch it to the client */
private function f_handle_userData(BSSAP_ConnHdlr client, PDU_BSSAP bssap)
runs on BSSMAP_Emulation_CT {
	/* decode + send decoded BSSAP to client */

	/* BSC Side: If this is an assignment command, store CIC */
	if (ischosen(bssap.pdu.bssmap.assignmentRequest) and
	    ispresent(bssap.pdu.bssmap.assignmentRequest.circuitIdentityCode)) {
		var BSSMAP_IE_CircuitIdentityCode cic_ie :=
			bssap.pdu.bssmap.assignmentRequest.circuitIdentityCode;
		var integer cic := (oct2int(cic_ie.cicHigh) * 256) + oct2int(cic_ie.cicLow);
		f_comp_store_cic(client, cic);
	}

	if (ischosen(bssap.pdu.dtap) and g_bssmap_ops.decode_dtap) {
		if (g_bssmap_ops.role_ms) {
			/* we are the MS, so any message to us must be MT */
			var PDU_DTAP_MT mt := {
				dlci := bssap.dlci,
				dtap := dec_PDU_ML3_NW_MS(bssap.pdu.dtap)
			};
			CLIENT.send(mt) to client;
		} else {
			/* we are the Network, so any message to us must be MO */
			var PDU_DTAP_MO mo := {
				dlci := bssap.dlci,
				dtap := dec_PDU_ML3_MS_NW(bssap.pdu.dtap)
			};
			CLIENT.send(mo) to client;
		}
	} else {
		CLIENT.send(bssap) to client;
	}
}

/* call-back type, to be provided by specific implementation; called when new SCCP connection
 * arrives */
type function BssmapCreateCallback(BSSAP_N_CONNECT_ind conn_ind, charstring id)
runs on BSSMAP_Emulation_CT return BSSAP_ConnHdlr;

type function BssmapUnitdataCallback(PDU_BSSAP bssap)
runs on BSSMAP_Emulation_CT return template PDU_BSSAP;

type record BssmapOps {
	BssmapCreateCallback create_cb,
	BssmapUnitdataCallback unitdata_cb,
	boolean decode_dtap,
	boolean role_ms
}

function main(BssmapOps ops, charstring id) runs on BSSMAP_Emulation_CT {

	g_bssmap_id := id;
	g_bssmap_ops := ops;
	f_conn_table_init();
	f_expect_table_init();

	while (true) {
		var BSSAP_N_UNITDATA_ind ud_ind;
		var BSSAP_N_CONNECT_ind conn_ind;
		var BSSAP_N_CONNECT_cfm conn_cfm;
		var BSSAP_N_DATA_ind data_ind;
		var BSSAP_N_DISCONNECT_ind disc_ind;
		var BSSAP_Conn_Req creq;
		var BSSAP_ConnHdlr vc_conn;
		var PDU_BSSAP bssap;
		var PDU_DTAP_MO dtap_mo;
		var PDU_DTAP_MT dtap_mt;
		var MgcpCommand mgcp_req;
		var MgcpResponse mgcp_resp;
		var BSSAP_ConnHdlr vc_hdlr;
		var octetstring l3_info;

		alt {
		/* SCCP -> Client: UNIT-DATA (connectionless SCCP) from a BSC */
		[] BSSAP.receive(BSSAP_N_UNITDATA_ind:?) -> value ud_ind {
			/* Connectionless Procedures like RESET */
			var template PDU_BSSAP resp;
			resp := ops.unitdata_cb.apply(ud_ind.userData);
			if (isvalue(resp)) {
				BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress,
								ud_ind.calledAddress, resp));
			}
			}

		/* SCCP -> Client: new connection from BSC */
		[] BSSAP.receive(BSSAP_N_CONNECT_ind:?) -> value conn_ind {
			vc_conn := ops.create_cb.apply(conn_ind, id);
			/* store mapping between client components and SCCP connectionId */
			f_conn_table_add(vc_conn, conn_ind.connectionId);
			/* handle user payload */
			f_handle_userData(vc_conn, conn_ind.userData);
			/* confirm connection establishment */
			BSSAP.send(ts_BSSAP_CONNECT_res(conn_ind.connectionId, omit));
			}

		/* SCCP -> Client: connection-oriented data in existing connection */
		[] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value data_ind {
			vc_conn := f_comp_by_conn_id(data_ind.connectionId);
			if (ispresent(data_ind.userData)) {
				f_handle_userData(vc_conn, data_ind.userData);
			}
			}

		/* SCCP -> Client: disconnect of an existing connection */
		[] BSSAP.receive(BSSAP_N_DISCONNECT_ind:?) -> value disc_ind {
			vc_conn := f_comp_by_conn_id(disc_ind.connectionId);
			if (ispresent(disc_ind.userData)) {
				f_handle_userData(vc_conn, disc_ind.userData);
			}
			/* notify client about termination */
			var BSSAP_Conn_Prim prim := MSC_CONN_PRIM_DISC_IND;
			CLIENT.send(prim) to vc_conn;
			f_conn_table_del(disc_ind.connectionId);
			/* TOOD: return confirm to other side? */
			}

		/* SCCP -> Client: connection confirm for outbound connection */
		[] BSSAP.receive(BSSAP_N_CONNECT_cfm:?) -> value conn_cfm {
			vc_conn := f_comp_by_conn_id(conn_cfm.connectionId);
			var BSSAP_Conn_Prim prim := MSC_CONN_PRIM_CONF_IND;
			CLIENT.send(prim) to vc_conn;
			/* handle user payload */
			if (ispresent(conn_cfm.userData)) {
				f_handle_userData(vc_conn, conn_cfm.userData);
			}
			}

		/* Disconnect request client -> SCCP */
		[] CLIENT.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_REQ) -> sender vc_conn {
			var integer conn_id := f_conn_id_by_comp(vc_conn);
			BSSAP.send(ts_BSSAP_DISC_req(conn_id, 0));
			f_conn_table_del(conn_id);
			}

		/* BSSAP from client -> SCCP */
		[] CLIENT.receive(BSSAP_Conn_Req:?) -> value creq sender vc_conn {
			var integer conn_id;
			/* send to dispatcher */

			if (f_comp_known(vc_conn) == false) {
				/* unknown client, create new connection */
				conn_id := f_gen_conn_id();

				/* store mapping between client components and SCCP connectionId */
				f_conn_table_add(vc_conn, conn_id);

				BSSAP.send(ts_BSSAP_CONNECT_req(creq.addr_peer, creq.addr_own, conn_id,
								creq.bssap));
			} else {
				/* known client, send via existing connection */
				conn_id := f_conn_id_by_comp(vc_conn);
				BSSAP.send(ts_BSSAP_DATA_req(conn_id, creq.bssap));
			}

			}

		[] CLIENT.receive(PDU_BSSAP:?) -> value bssap sender vc_conn {
			var integer conn_id := f_conn_id_by_comp(vc_conn);
			/* send it to dispatcher */
			BSSAP.send(ts_BSSAP_DATA_req(conn_id, bssap));
			}

		[g_bssmap_ops.role_ms] CLIENT.receive(PDU_DTAP_MO:?) -> value dtap_mo sender vc_conn {
			var integer conn_id := f_conn_id_by_comp(vc_conn);
			/* convert from decoded DTAP to encoded DTAP */
			var octetstring l3_enc := enc_PDU_ML3_MS_NW(dtap_mo.dtap);
			bssap := valueof(ts_BSSAP_DTAP(l3_enc, dtap_mo.dlci));
			BSSAP.send(ts_BSSAP_DATA_req(conn_id, bssap));
			}

		[not g_bssmap_ops.role_ms] CLIENT.receive(PDU_DTAP_MT:?) -> value dtap_mt sender vc_conn {
			var integer conn_id := f_conn_id_by_comp(vc_conn);
			/* convert from decoded DTAP to encoded DTAP */
			var octetstring l3_enc := enc_PDU_ML3_NW_MS(dtap_mt.dtap);
			bssap := valueof(ts_BSSAP_DTAP(l3_enc, dtap_mo.dlci));
			BSSAP.send(ts_BSSAP_DATA_req(conn_id, bssap));
			}


		/* Handling of MGCP in IPA SCCPLite case.  This predates 3GPP AoIP
		 * and uses a MGCP session in parallel to BSSAP.  BSSAP uses CIC
		 * as usual, and MGCP uses "CIC@mgw" endpoint naming, where CIC
		 * is printed as hex string, e.g. a@mgw for CIC 10 */

		/* CLIENT -> MGCP */
		[] CLIENT.receive(MgcpCommand:?) -> value mgcp_req sender vc_conn {
			/* MGCP request from Handler (we're MSC) */
			/* store the transaction ID we've seen */
			f_comp_store_mgcp_tid(vc_conn, mgcp_req.line.trans_id);
			/* simply forward any MGCP from the client to the port */
			MGCP.send(mgcp_req);
			}
		[] CLIENT.receive(MgcpResponse:?) -> value mgcp_resp sender vc_conn {
			/* MGCP response from Handler (we're BSC/MGW) */
			/* simply forward any MGCP from the client to the port */
			MGCP.send(mgcp_resp);
			}

		/* MGCP -> CLIENT */
		[] MGCP.receive(MgcpCommand:?) -> value mgcp_req {
			/* MGCP request from network side (we're BSC/MGW) */
			/* Extract CIC from local part of endpoint name */
			var integer cic := f_mgcp_ep_extract_cic(mgcp_req.line.ep);
			if (match(mgcp_req, tr_RSIP) and f_cic_known(cic) == false) {
				/* ignore RSIP for unknown CIC */
			} else {
				/* Resolve the vc_conn by the CIC */
				vc_conn := f_comp_by_cic(cic);
				CLIENT.send(mgcp_req) to vc_conn;
			}
			}
		[] MGCP.receive(MgcpResponse:?) -> value mgcp_resp {
			/* MGCP response from network side (we're MSC) */
			/* Resolve the vc_conn by the transaction ID */
			vc_conn := f_comp_by_mgcp_tid(mgcp_resp.line.trans_id);
			CLIENT.send(mgcp_resp) to vc_conn;
			}


		[] PROC.getcall(BSSMAPEM_register:{?,?}) -> param(l3_info, vc_hdlr) {
			f_create_expect(l3_info, vc_hdlr);
			PROC.reply(BSSMAPEM_register:{l3_info, vc_hdlr});
			}

		}
	}
}

private function f_mgcp_ep_extract_cic(charstring inp) return integer {
	var charstring local_part := regexp(inp, "(*)@*", 0);
	return hex2int(str2hex(local_part));

}

/***********************************************************************
 * "Expect" Handling (mapping for expected incoming SCCP connections)
 ***********************************************************************/

/* data about an expected future incoming connection */
type record ExpectData {
	/* L3 payload based on which we can match it */
	octetstring l3_payload optional,
	/* component reference for this connection */
	BSSAP_ConnHdlr vc_conn
}

/* procedure based port to register for incoming connections */
signature BSSMAPEM_register(in octetstring l3, in BSSAP_ConnHdlr hdlr);

type port BSSMAPEM_PROC_PT procedure {
	inout BSSMAPEM_register;
} with { extension "internal" };

/* CreateCallback that can be used as create_cb and will use the expectation table */
function ExpectedCreateCallback(BSSAP_N_CONNECT_ind conn_ind, charstring id)
runs on BSSMAP_Emulation_CT return BSSAP_ConnHdlr {
	var BSSAP_ConnHdlr ret := null;
	var octetstring l3_info;
	var integer i;

	if (not ischosen(conn_ind.userData.pdu.bssmap.completeLayer3Information)) {
		setverdict(fail, "N-CONNECT.ind with L3 != COMPLETE L3");
		return ret;
	}
	l3_info := conn_ind.userData.pdu.bssmap.completeLayer3Information.layer3Information.layer3info;

	for (i := 0; i < sizeof(ExpectTable); i:= i+1) {
		if (not ispresent(ExpectTable[i].l3_payload)) {
			continue;
		}
		if (l3_info == ExpectTable[i].l3_payload) {
			ret := ExpectTable[i].vc_conn;
			/* release this entry to be used again */
			ExpectTable[i].l3_payload := omit;
			ExpectTable[i].vc_conn := null;
			log("Found Expect[", i, "] for ", l3_info, " handled at ", ret);
			/* return the component reference */
			return ret;
		}
	}
	setverdict(fail, "Couldn't find Expect for incoming connection ", conn_ind);
	return ret;
}

private function f_create_expect(octetstring l3, BSSAP_ConnHdlr hdlr)
runs on BSSMAP_Emulation_CT {
	var integer i;
	for (i := 0; i < sizeof(ExpectTable); i := i+1) {
		if (not ispresent(ExpectTable[i].l3_payload)) {
			ExpectTable[i].l3_payload := l3;
			ExpectTable[i].vc_conn := hdlr;
			log("Created Expect[", i, "] for ", l3, " to be handled at ", hdlr);
			return;
		}
	}
	setverdict(fail, "No space left in ExpectTable");
}

private function f_expect_table_init()
runs on BSSMAP_Emulation_CT {
	for (var integer i := 0; i < sizeof(ExpectTable); i := i+1) {
		ExpectTable[i].l3_payload := omit;
	}
}

}
