module REMSIM_Tests {

/* Implementation of RSPRO Client in TTCN-3.
 * (C) 2019 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 IPL4asp_Types all;
import from RSPRO all;
import from RSPRO_Types all;
import from IPA_Types all;
import from IPA_Emulation all;


modulepar {
	charstring mp_bankd_ip := "127.0.0.1";
	integer mp_bankd_port := 9999;

	charstring mp_server_ip := "127.0.0.1";
	integer mp_server_port := 9998;

	integer mp_rsres_port := 9997;
}

const integer NUM_CLIENT := 3;

type record RSPRO_Client {
	IPA_Emulation_CT	vc_IPA,
	IPA_CCM_Parameters	ccm_pars,
	charstring		id,
	ComponentIdentity	rspro_id,

	ClientSlot		rspro_client_slot optional,
	BankId			rspro_bank_id optional,
	SlotNumber		rspro_bank_nslots optional
};

type component rspro_client_CT {
	var RSPRO_Client	rspro[NUM_CLIENT];
	port IPA_RSPRO_PT	RSPRO[NUM_CLIENT];
};

private altstep as_ignore_id_ack(integer i := 0) runs on rspro_client_CT {
	[] RSPRO[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) { repeat; }
}

function f_rspro_init(inout RSPRO_Client clnt, charstring dst_host, integer dst_port,
		      ComponentIdentity rspro_id, integer i)
runs on rspro_client_CT
{
	timer T := 4.0;

	clnt.id := "RSPRO" & int2str(i);
	clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id);
	clnt.ccm_pars := c_IPA_default_ccm_pars;
	clnt.ccm_pars.name := "Osmocom TTCN-3 RSPRO client simulator";
	clnt.rspro_id := rspro_id;

	/* leave it up to the caller to set those */
	clnt.rspro_client_slot := omit;
	clnt.rspro_bank_id := omit;
	clnt.rspro_bank_nslots := omit;

	map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
	connect(clnt.vc_IPA:IPA_RSPRO_PORT, self:RSPRO[i]);

	clnt.vc_IPA.start(IPA_Emulation.main_client(dst_host, dst_port, "", 10000+i, clnt.ccm_pars));

	T.start;
	alt {
	[] RSPRO[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
	[] T.timeout {
		setverdict(fail, "Timeout waiting for ASP_IPA_EVENT_UP");
		mtc.stop;
		}
	}
	T.start;
	alt {
	[] RSPRO[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) { }
	[] T.timeout {
		setverdict(fail, "Timeout waiting for ASP_IPA_EVENT_ID_ACK");
		mtc.stop;
		}
	}


	activate(as_ignore_id_ack(i));
}

function f_rspro_fini(inout RSPRO_Client clnt, integer i)
runs on rspro_client_CT {
	clnt.vc_IPA.stop;
	disconnect(clnt.vc_IPA:IPA_RSPRO_PORT, self:RSPRO[i]);
	unmap(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
}


function f_rspro_exp(template RsproPDU exp, integer i := 0)
runs on rspro_client_CT return RsproPDU
{
	var RsproPDU pdu;

	timer T := 10.0;
	T.start;
	alt {
	[] RSPRO[i].receive(exp) -> value pdu {
		setverdict(pass);
		}
	[] RSPRO[i].receive(RsproPDU:?) -> value pdu {
		setverdict(fail, "Received unexpected RPSRO", pdu);
		mtc.stop;
		}
	[] RSPRO[i].receive {
		setverdict(fail, "Received unexpected != RPSRO");
		mtc.stop;
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for ", exp);
		mtc.stop;
		}
	}
	return pdu;
}

function f_rspro_exp_disconnect(integer i := 0)
runs on rspro_client_CT {
	timer T := 10.0;
	T.start;
	alt {
	[] RSPRO[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
		setverdict(pass);
		}
	[] T.timeout {
		setverdict(fail, "Timeout expecting disconnect");
		mtc.stop;
		}
	}
}


function f_rspro_connect_client(integer i, template ResultCode exp_res := ok) runs on rspro_client_CT
{
	select (rspro[i].rspro_id.type_) {
	case (remsimClient) {
		RSPRO[i].send(ts_RSPRO_ConnectClientReq(rspro[i].rspro_id, rspro[i].rspro_client_slot));
		f_rspro_exp(tr_RSPRO_ConnectClientRes(?, exp_res), i);
		}
	case (remsimBankd) {
		var template IpAddress ip := ts_IPv4(mp_bankd_ip);
		RSPRO[i].send(ts_RSPRO_ConnectBankReq(rspro[i].rspro_id, rspro[i].rspro_bank_id,
						      rspro[i].rspro_bank_nslots,
						      ts_IpPort(ip, mp_bankd_port)));
		f_rspro_exp(tr_RSPRO_ConnectBankRes(?, exp_res), i);
		}
	case else {
		setverdict(fail, "Unsupported type ", rspro[i].rspro_id.type_);
		mtc.stop;
		}
	}
}

function f_rspro_connect_clients() runs on rspro_client_CT
{
	var integer i;

	for (i := 0; i < NUM_CLIENT; i := i+1) {
		select (rspro[i].rspro_id.type_) {
		case (remsimClient) {
			RSPRO[i].send(ts_RSPRO_ConnectClientReq(rspro[i].rspro_id,
								rspro[i].rspro_client_slot));
			}
		case (remsimBankd) {
			var template IpAddress ip := ts_IPv4(mp_bankd_ip);
			RSPRO[i].send(ts_RSPRO_ConnectBankReq(rspro[i].rspro_id, rspro[i].rspro_bank_id,
							      rspro[i].rspro_bank_nslots,
							      ts_IpPort(ip, mp_bankd_port)));
			}
		}
	}
	for (i := 0; i < NUM_CLIENT; i := i+1) {
		select (rspro[i].rspro_id.type_) {
		case (remsimClient) {
			f_rspro_exp(tr_RSPRO_ConnectClientRes(?, ResultCode:ok), i);
			}
		case (remsimBankd) {
			f_rspro_exp(tr_RSPRO_ConnectBankRes(?, ResultCode:ok), i);
			}
		}
	}
}

/* transceive a TPDU from modem to card (and back) */
function f_rspro_xceive_mdm2card(integer idx, BankSlot bs, template (value) octetstring data,
				 template (value) TpduFlags flags) runs on rspro_client_CT return octetstring {
	var RsproPDU rx;
	RSPRO[idx].send(ts_RSPRO_TpduModemToCard(rspro[idx].rspro_client_slot, bs, flags, data));
	rx := f_rspro_exp(tr_RSPRO_TpduCardToModem(bs, rspro[idx].rspro_client_slot, ?, ?));
	return rx.msg.tpduCardToModem.data;
}

/* handle an incoming CreateMapping + ACK it */
altstep as_rspro_create_mapping(integer i, template ClientSlot cslot := ?, template BankSlot bslot := ?,
				template ResultCode res := ok)
runs on rspro_client_CT {
	var RsproPDU rx;
	[] RSPRO[i].receive(tr_RSPRO_CreateMappingReq(cslot, bslot)) -> value rx {
		RSPRO[i].send(ts_RSPRO_CreateMappingRes(res));
		}
}

/* handle an incoming RemoveMapping + ACK it */
altstep as_rspro_remove_mapping(integer i, template ClientSlot cslot := ?, template BankSlot bslot := ?,
				template ResultCode res := ok)
runs on rspro_client_CT {
	var RsproPDU rx;
	[] RSPRO[i].receive(tr_RSPRO_RemoveMappingReq(cslot, bslot)) -> value rx {
		RSPRO[i].send(ts_RSPRO_RemoveMappingRes(res));
		}
}

altstep as_rspro_cfg_client_id(integer i, template ClientSlot cslot := ?,
				template (value) ResultCode res := ok)
runs on rspro_client_CT {
	var RsproPDU rx;
	[] RSPRO[i].receive(tr_RSPRO_ConfigClientIdReq(cslot)) -> value rx {
		RSPRO[i].send(ts_RSPRO_ConfigClientIdRes(res));
		}
}

altstep as_rspro_cfg_client_bank(integer i, template BankSlot bslot := ?,
				 template IpPort ip_port := ?,
				template (value) ResultCode res := ok)
runs on rspro_client_CT {
	var RsproPDU rx;
	[] RSPRO[i].receive(tr_RSPRO_ConfigClientBankReq(bslot, ip_port)) -> value rx {
		RSPRO[i].send(ts_RSPRO_ConfigClientBankRes(res));
		}
}



}
