module SMPP_Emulation {

/* SMPP Emulation layer, sitting on top of SMPP_CodecPort.
 *
 * (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 Osmocom_Types all;
import from General_Types all;
import from SMPP_Types all;
import from SMPP_Templates all;
import from SMPP_CodecPort all;
import from SMPP_CodecPort_CtrlFunct all;
import from IPL4asp_Types all;
import from IPL4asp_PortType all;
import from Socket_API_Definitions all;

/* general "base class" component definition, of which specific implementations
 * derive themselves by menas of the "extends" feature */
type component SMPP_ConnHdlr {
	/* port towards SPPP_Emulation_CT */
	port SMPP_Conn_PT SMPP;
	port SMPPEM_PROC_PT SMPP_PROC;
}


type component SMPP_Emulation_CT {
	/* down-facing port to SMPP Codec port */
	port SMPP_CODEC_PT SMPP_PORT;
	var IPL4asp_Types.ConnectionId g_smpp_conn_id := -1;

	var integer g_seq := 1;

	/* up-facing port to Clients */
	port SMPP_Conn_PT SMPP_CLIENT;
	port SMPPEM_PROC_PT SMPP_PROC;

	var TransactionData TransactionTable[32];
	var ExpectData ExpectTable[32];
}

type port SMPP_Conn_PT message {
	inout SMPP_PDU;
} with { extension "internal" };

type record TransactionData {
	uint32_t	tid optional,
	SMPP_ConnHdlr	vc_conn
}

type record ExpectData {
	SMPP_TON	dst_ton optional,
	SMPP_NPI	dst_npi optional,
	charstring	dst_addr,
	SMPP_ConnHdlr	vc_conn
}

private function f_trans_id_known(uint32_t tid)
runs on SMPP_Emulation_CT return boolean {
	for (var integer i := 0; i < sizeof(TransactionTable); i := i+1) {
		if (TransactionTable[i].tid == tid) {
			return true;
		}
	}
	return false;
}

private function f_comp_known(SMPP_ConnHdlr client)
runs on SMPP_Emulation_CT return boolean {
	for (var integer i := 0; i < sizeof(TransactionTable); i := i+1) {
		if (TransactionTable[i].vc_conn == client) {
			return true;
		}
	}
	return false;
}

private function f_comp_by_trans_id(uint32_t tid)
runs on SMPP_Emulation_CT return SMPP_ConnHdlr {
	for (var integer i := 0; i < sizeof(TransactionTable); i := i+1) {
		if (TransactionTable[i].tid == tid) {
			return TransactionTable[i].vc_conn;
		}
	}
	setverdict(fail, "No componten for SMPP TID ", tid);
	mtc.stop;
}


private function f_trans_table_init()
runs on SMPP_Emulation_CT {
	for (var integer i := 0; i < sizeof(TransactionTable); i := i+1) {
		TransactionTable[i].vc_conn := null;
		TransactionTable[i].tid := omit;
	}
}

private function f_trans_table_add(SMPP_ConnHdlr vc_conn, uint32_t trans_id)
runs on SMPP_Emulation_CT {
	for (var integer i := 0; i < sizeof(TransactionTable); i := i+1) {
		if (TransactionTable[i].vc_conn == null) {
			TransactionTable[i].vc_conn := vc_conn;
			TransactionTable[i].tid := trans_id;
			return;
		}
	}
	testcase.stop("SMPP Trans table full!");
}

private function f_trans_table_del(uint32_t trans_id)
runs on SMPP_Emulation_CT {
	for (var integer i := 0; i < sizeof(TransactionTable); i := i+1) {
		if (TransactionTable[i].tid == trans_id) {
			TransactionTable[i].vc_conn := null;
			TransactionTable[i].tid := omit;
			return;
		}
	}
	setverdict(fail, "SMPP Trans table attempt to delete non-existant ", trans_id);
	mtc.stop;
}



function f_connect(charstring remote_host, IPL4asp_Types.PortNumber remote_port,
		   charstring local_host, IPL4asp_Types.PortNumber local_port)
runs on SMPP_Emulation_CT {
	var IPL4asp_Types.Result res;
	res := SMPP_CodecPort_CtrlFunct.f_IPL4_connect(SMPP_PORT, remote_host, remote_port,
							local_host, local_port, 0, { tcp :={} });
	if (not ispresent(res.connId)) {
		setverdict(fail, "Could not connect to SMPP port, check your configuration");
		mtc.stop;
	}
	g_smpp_conn_id := res.connId;
}

/* Function to use to bind to a local port as IPA server, accepting remote clients */
function f_bind(charstring local_host, IPL4asp_Types.PortNumber local_port)
runs on SMPP_Emulation_CT {
	var IPL4asp_Types.Result res;
	res := SMPP_CodecPort_CtrlFunct.f_IPL4_listen(SMPP_PORT, local_host, local_port, { tcp:={} });
	g_smpp_conn_id := res.connId;
}


function main_server(EsmePars pars, charstring local_host, integer local_port)
runs on SMPP_Emulation_CT {
	f_bind(local_host, local_port);
	f_mainloop(pars);
}

function main_client(EsmePars pars, charstring remote_host, integer remote_port,
			charstring local_host, integer local_port)
runs on SMPP_Emulation_CT {
	f_connect(remote_host, remote_port, local_host, local_port);
	f_mainloop(pars);
}

type enumerated EsmeMode {
	MODE_TRANSMITTER,
	MODE_RECEIVER,
	MODE_TRANSCEIVER
}
type record EsmePars {
	EsmeMode	mode,
	SMPP_Bind	bind,
	boolean		esme_role
}

private function f_tx_smpp(template (value) SMPP_PDU pdu) runs on SMPP_Emulation_CT {
	pdu.header.seq_num := g_seq;
	SMPP_PORT.send(ts_SMPP_Send(g_smpp_conn_id, pdu));
	g_seq := g_seq+1;
}

private function f_rx_smpp(template SMPP_PDU pdu) runs on SMPP_Emulation_CT {
	timer T_wait := 3.0;
	T_wait.start;
	alt {
	[] SMPP_PORT.receive(tr_SMPP_Recv(g_smpp_conn_id, pdu)) { }
	[] T_wait.timeout {
		setverdict(fail, "Timeout waiting for ", pdu);
		mtc.stop;
		}
	}
}

/* default altstep which we use throughout */
private altstep as_smpp() runs on SMPP_Emulation_CT {
	var SMPP_ConnHdlr vc_conn;
	var SMPP_RecvFrom smpp_rf;
	/* Answer to ENQUIRE LINK */
	[] SMPP_PORT.receive(tr_SMPP_Recv(g_smpp_conn_id,
			     tr_SMPP(c_SMPP_command_id_enquire_link, ESME_ROK))) {
		f_tx_smpp(ts_SMPP_ENQ_LINK_resp);
		}
	[] SMPP_PORT.receive(tr_SMPP_Recv(g_smpp_conn_id,
			     tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK))) -> value smpp_rf {
		/* TODO: dispatch to ConnHdlr based on some kind of expect mechanism? */
		vc_conn := f_exp_lookup(smpp_rf.msg.body.alert_notif.source_addr_ton,
					smpp_rf.msg.body.alert_notif.source_addr_npi,
					smpp_rf.msg.body.alert_notif.source_addr);
		SMPP_CLIENT.send(smpp_rf.msg) to vc_conn;
		}
	[] SMPP_PORT.receive {
		setverdict(fail, "Unexpected SMPP from peer");
		mtc.stop;
		}
}

function f_mainloop(EsmePars pars)
runs on SMPP_Emulation_CT {

	/* Set function for dissecting the binary stream into packets */
	var f_IPL4_getMsgLen vl_f := refers(f_IPL4_fixedMsgLen);
	/* Offset: 0, size of length: 4, delta: 0, multiplier: 1, big-endian */
	SMPP_CodecPort_CtrlFunct.f_IPL4_setGetMsgLen(SMPP_PORT, g_smpp_conn_id, vl_f, {0, 4, 0, 1, 0});

	f_trans_table_init();
	f_expect_table_init();

	/* activate default altstep */
	var default d := activate(as_smpp());

	if (pars.esme_role) {
		/* BIND to SMSC */
		select (pars.mode) {
		case (MODE_TRANSMITTER) {
			f_tx_smpp(ts_SMPP_BIND_TX(pars.bind));
			/* FIXME: do we have to check for SEQ? */
			f_rx_smpp(tr_SMPP(c_SMPP_command_id_bind_transmitter_resp, ESME_ROK, g_seq));
			}
		case (MODE_RECEIVER) {
			f_tx_smpp(ts_SMPP_BIND_RX(pars.bind));
			/* FIXME: do we have to check for SEQ? */
			f_rx_smpp(tr_SMPP(c_SMPP_command_id_bind_receiver_resp, ESME_ROK, g_seq));
			}
		case (MODE_TRANSCEIVER) {
			f_tx_smpp(ts_SMPP_BIND_TRX(pars.bind));
			/* FIXME: do we have to check for SEQ? */
			f_rx_smpp(tr_SMPP(c_SMPP_command_id_bind_transceiver_resp, ESME_ROK));
			}
		}
	} else {
		var SMPP_Bind_resp bresp := {
			system_id := pars.bind.system_id,
			opt_pars := {}
		}
		/* Expect bind from ESME */
		select (pars.mode) {
		case (MODE_TRANSMITTER) {
			f_rx_smpp(tr_SMPP_BIND_TX(pars.bind));
			/* FIXME: do we have to check for SEQ? */
			f_tx_smpp(ts_SMPP_BIND_TX_resp(ESME_ROK, bresp));
			}
		case (MODE_RECEIVER) {
			f_rx_smpp(tr_SMPP_BIND_RX(pars.bind));
			/* FIXME: do we have to check for SEQ? */
			f_tx_smpp(ts_SMPP_BIND_RX_resp(ESME_ROK, bresp));
			}
		case (MODE_TRANSCEIVER) {
			f_rx_smpp(tr_SMPP_BIND_TRX(pars.bind));
			/* FIXME: do we have to check for SEQ? */
			f_tx_smpp(ts_SMPP_BIND_TRX_resp(ESME_ROK, bresp));
			}
		}
	}

	while (true) {
		var SMPP_ConnHdlr vc_conn;
		var SMPP_RecvFrom smpp_rf;
		var SMPP_PDU smpp;
		var charstring dest_addr;
		alt {
		/* SMSC -> CLIENT: response, map by seq_nr */
		[pars.esme_role] SMPP_PORT.receive(tr_SMPP_Recv(g_smpp_conn_id,
							tr_SMPP_esme_resp)) -> value smpp_rf {
			var uint32_t trans_id := smpp_rf.msg.header.seq_num;
			if (f_trans_id_known(trans_id)) {
				vc_conn := f_comp_by_trans_id(trans_id);
				SMPP_CLIENT.send(smpp_rf.msg) to vc_conn;
				f_trans_table_del(trans_id);
			} else {
				log("Received SMPP response for unknown trans_id ", smpp_rf);
				/* FIXME */
			}
			}
		/* SMSC -> CLIENT: DELIVER-SM.req */
		[pars.esme_role] SMPP_PORT.receive(tr_SMPP_Recv(g_smpp_conn_id,
				tr_SMPP(c_SMPP_command_id_deliver_sm, ESME_ROK))) -> value smpp_rf {
			vc_conn := f_exp_lookup(smpp_rf.msg.body.deliver_sm.dest_addr_ton,
						smpp_rf.msg.body.deliver_sm.dest_addr_npi,
						smpp_rf.msg.body.deliver_sm.destination_addr);
			SMPP_CLIENT.send(smpp_rf.msg) to vc_conn;
			}

		/* record seq_nr for commands from CLIENT -> SMSC */
		[pars.esme_role] SMPP_CLIENT.receive(tr_SMPP_esme_req) -> value smpp sender vc_conn {
			/* register current seq_nr/trans_id */
			f_trans_table_add(vc_conn, g_seq);
			f_tx_smpp(smpp);
			}
		/* pass responses 1:1 through from CLIENT -> SMSC */
		[pars.esme_role] SMPP_CLIENT.receive(tr_SMPP_smsc_resp) -> value smpp sender vc_conn {
			SMPP_PORT.send(ts_SMPP_Send(g_smpp_conn_id, smpp));
			}

		[] SMPP_PROC.getcall(SMPPEM_register:{?,?}) -> param(dest_addr, vc_conn) {
			f_create_expect(dest_addr, vc_conn);
			SMPP_PROC.reply(SMPPEM_register:{dest_addr, vc_conn}) to vc_conn;
			}
		}
	}
}

/* Requests from ESME -> SMSC */
template OCT4 SMPP_esme_req := (
	c_SMPP_command_id_submit_sm,
	c_SMPP_command_id_replace_sm,
	c_SMPP_command_id_cancel_sm,
	c_SMPP_command_id_submit_multi
);
template SMPP_PDU tr_SMPP_esme_req := tr_SMPP(SMPP_esme_req, ?);

/* Responses from ESME -> SMSC */
template OCT4 SMPP_esme_resp := (
	c_SMPP_command_id_submit_sm_resp,
	c_SMPP_command_id_replace_sm_resp,
	c_SMPP_command_id_cancel_sm_resp,
	c_SMPP_command_id_submit_multi_resp
);
template SMPP_PDU tr_SMPP_esme_resp := tr_SMPP(SMPP_esme_resp, ?);

/* Requests from SMSC -> ESME */
template OCT4 SMPP_smsc_req := (
	c_SMPP_command_id_deliver_sm
);
template SMPP_PDU tr_SMPP_smsc_req := tr_SMPP(SMPP_smsc_req, ?);

/* Responses from SMSC -> ESME */
template OCT4 SMPP_smsc_resp := (
	c_SMPP_command_id_deliver_sm_resp
);
template SMPP_PDU tr_SMPP_smsc_resp := tr_SMPP(SMPP_smsc_resp, ?);



signature SMPPEM_register(charstring dst_addr, SMPP_ConnHdlr hdlr);

type port SMPPEM_PROC_PT procedure {
	inout SMPPEM_register;
} with { extension "internal" };

private function f_create_expect(charstring dest_number, SMPP_ConnHdlr hdlr)
runs on SMPP_Emulation_CT {
	for (var integer i := 0; i < sizeof(ExpectTable); i := i+1) {
		if (ExpectTable[i].dst_addr == dest_number) {
			ExpectTable[i] := {
				dst_ton := omit,
				dst_npi := omit,
				dst_addr := dest_number,
				vc_conn := hdlr
			}
			return;
		}
	}
	for (var integer i := 0; i < sizeof(ExpectTable); i := i+1) {
		if (ExpectTable[i].vc_conn == null) {
			ExpectTable[i] := {
				dst_ton := omit,
				dst_npi := omit,
				dst_addr := dest_number,
				vc_conn := hdlr
			}
			return;
		}
	}
	testcase.stop("No space left in SmppExpectTable");
}

private function f_exp_lookup(SMPP_TON ton, SMPP_NPI npi, charstring dst)
runs on SMPP_Emulation_CT return SMPP_ConnHdlr {
	for (var integer i := 0; i < sizeof(ExpectTable); i := i+1) {
		if (ExpectTable[i].vc_conn != null and ExpectTable[i].dst_addr == dst) {
			if (ispresent(ExpectTable[i].dst_ton) and ExpectTable[i].dst_ton != ton) {
				continue;
			}
			if (ispresent(ExpectTable[i].dst_npi) and ExpectTable[i].dst_npi != npi) {
				continue;
			}
			return ExpectTable[i].vc_conn;
		}
	}
	return null;
}
private function f_expect_table_init()
runs on SMPP_Emulation_CT {
	for (var integer i := 0; i < sizeof(ExpectTable); i := i+1) {
		ExpectTable[i] := {
			dst_ton := omit,
			dst_npi := omit,
			dst_addr := "",
			vc_conn := null
		};
	}
}





/* client/conn_hdlr side function to use procedure port to create expect in emulation */
function f_create_smpp_expect(charstring dest_number) runs on SMPP_ConnHdlr {
	SMPP_PROC.call(SMPPEM_register:{dest_number, self}) {
		[] SMPP_PROC.getreply(SMPPEM_register:{?,?}) {};
	}
}


}
