module RemsimBankd_Tests {

/* Integration Tests for osmo-remsim-bankd
 * (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
 *
 * This test suite tests osmo-remsim-bankd by attaching to the external interfaces
 * such as RSPRO for simulated clients + server.
 */

import from Osmocom_Types all;
import from IPA_Emulation all;
import from Misc_Helpers all;

import from VPCD_Types all;
import from VPCD_CodecPort all;
import from VPCD_Adapter all;

import from RSPRO all;
import from RSRES all;
import from RSPRO_Types all;
import from RSPRO_Server all;
import from REMSIM_Tests all;

modulepar {
	integer mp_bank_id := 1;
	integer mp_num_slots := 8;
}

/* We implement a RSPRO server to simulate the remsim-server and a
   RSPRO client to simulate a remsim-client connecting to bankd */
type component bankd_test_CT extends rspro_server_CT, rspro_client_CT, VPCD_Adapter_CT {
}

private function f_init(boolean start_client := false) runs on bankd_test_CT {
	var ComponentIdentity srv_comp_id := valueof(ts_CompId(remsimServer, "ttcn-server"));

	f_rspro_srv_init(0, mp_server_ip, mp_server_port, srv_comp_id);

	if (start_client) {
		f_init_client(0);
	}
}

private function f_init_client(integer i := 0) runs on rspro_client_CT {
	var ComponentIdentity clnt_comp_id := valueof(ts_CompId(remsimClient, "ttcn-client"));
	f_rspro_init(rspro[0], mp_bankd_ip, mp_bankd_port, clnt_comp_id, 0);
	rspro[0].rspro_client_slot := { clientId := 23+i, slotNr := 0 };
}



/* Test if the bankd disconnects the TCP/IPA session if we don't respond to connectBankReq */
testcase TC_connectBankReq_timeout() runs on bankd_test_CT {
	timer T := 20.0;
	f_init();

	f_rspro_srv_exp(tr_RSPRO_ConnectBankReq(?, ?, ?));
	T.start;
	alt {
	[] RSPRO_SRV[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
		setverdict(pass);
		}
	[] RSPRO_SRV[0].receive { repeat; }
	[] T.timeout {
		setverdict(fail, "Timeout waiting for disconnect");
		}
	}
}

/* accept an inbound connection from bankd to simulated server */
testcase TC_connectBankReq() runs on bankd_test_CT {
	f_init();

	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

/* attempt to create a mapping */
testcase TC_createMapping() runs on bankd_test_CT {
	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	f_rspro_srv_reset_state(ok);
	var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
	var ClientSlot cs := { clientId := 23, slotNr := 42 };
	f_rspro_srv_create_slotmap(cs, bs);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

/* attempt to create a mapping for a slot that already has a mapping */
testcase TC_createMapping_busySlot() runs on bankd_test_CT {
	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	f_rspro_srv_reset_state(ok);
	var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
	var ClientSlot cs := { clientId := 23, slotNr := 42 };
	/* create the mapping the first time */
	f_rspro_srv_create_slotmap(cs, bs);
	/* re-create the mapping a second time */
	f_rspro_srv_create_slotmap(cs, bs);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

/* attempt to create a mapping for an out-of-range slot number */
testcase TC_createMapping_invalidSlot() runs on bankd_test_CT {
	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	f_rspro_srv_reset_state(ok);
	var BankSlot bs := { bankId := mp_bank_id, slotNr := 200 };
	var ClientSlot cs := { clientId := 23, slotNr := 42 };
	f_rspro_srv_create_slotmap(cs, bs, exp_res := illegalSlotId);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

/* attempt to create a mapping for an invalid bankID */
testcase TC_createMapping_invalidBank() runs on bankd_test_CT {
	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	f_rspro_srv_reset_state(ok);
	var BankSlot bs := { bankId := 200, slotNr := 0 };
	var ClientSlot cs := { clientId := 23, slotNr := 42 };
	f_rspro_srv_create_slotmap(cs, bs, exp_res := illegalBankId);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

/* attempt to remove a non-existant mapping */
testcase TC_removeMapping_unknownMap() runs on bankd_test_CT {
	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	f_rspro_srv_reset_state(ok);
	var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
	var ClientSlot cs := { clientId := 23, slotNr := 42 };
	f_rspro_srv_remove_slotmap(cs, bs, exp_res := unknownSlotmap);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

/* add and then remove a mapping, expect both to be successful */
testcase TC_removeMapping() runs on bankd_test_CT {
	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	f_rspro_srv_reset_state(ok);
	var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
	var ClientSlot cs := { clientId := 23, slotNr := 42 };
	f_rspro_srv_create_slotmap(cs, bs);
	f_rspro_srv_remove_slotmap(cs, bs);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

/* connect from client to bankd without specifying a clientId */
testcase TC_clientConnect_missingSlot() runs on bankd_test_CT {
	f_init_client(0);
	RSPRO[0].send(ts_RSPRO_ConnectClientReq(rspro[0].rspro_id, omit));
	f_rspro_exp(tr_RSPRO_ConnectClientRes(?, ResultCode:illegalClientId), 0);
	f_rspro_exp_disconnect(0);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

/* connect from client to bankd using a clientId for which bankd has no map */
testcase TC_clientConnect_unknown() runs on bankd_test_CT {
	f_init_client(0);
	f_rspro_connect_client(0, tr_Status_ok_or_nocard);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

/* connect from client to bankd using a clientSlot for which bankd has no map */


/* first connect client, then later add matching mapping from server */
testcase TC_clientConnect_createMapping() runs on bankd_test_CT {
	f_init_client(0);
	f_rspro_connect_client(0, tr_Status_ok_or_nocard);

	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);

	var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
	f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);
	f_sleep(10.0);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}


/* first add mapping, then connect matching client */
testcase TC_createMapping_clientConnect() runs on bankd_test_CT {
	/* FIXME: this would only be done in f_init_client(), but we need it before */
	rspro[0].rspro_client_slot := { clientId := 23+0, slotNr := 0 };

	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	f_rspro_srv_reset_state(ok);

	var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
	f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);

	f_sleep(1.0);

	f_init_client(0);
	f_rspro_connect_client(0, tr_Status_ok_or_nocard);
	/* FIXME: how to determine that bank correctly mapped us */
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

/* first add mapping, then connect client, then change mapping (expect disconnect) */
testcase TC_createMapping_connectClient_changeMapping() runs on bankd_test_CT {
	/* FIXME: this would only be done in f_init_client(), but we need it before */
	rspro[0].rspro_client_slot := { clientId := 23+0, slotNr := 0 };

	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	f_rspro_srv_reset_state(ok);

	/* create slotmap */
	var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
	f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);

	f_sleep(1.0);

	/* connect client */
	f_init_client(0);
	f_rspro_connect_client(0, tr_Status_ok_or_nocard);
	/* FIXME: how to determine that bank correctly mapped us */

	/* create another mapping for the same bank-slot */
	var ClientSlot cs := { clientId := 987, slotNr := 654 };
	f_rspro_srv_create_slotmap(cs, bs);

	/* expect client to be disconnected */
	timer T := 5.0;
	T.start;
	alt {
	[] RSPRO[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
		setverdict(pass);
		}
	[] RSPRO[0].receive {
		setverdict(fail, "Unexpected RSPRO on client connection");
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for client being disconnected");
		}
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

/* first add mapping, then connect client, then re-crete mapping (expect no disconnect) */
testcase TC_createMapping_connectClient_recreateMapping() runs on bankd_test_CT {
	/* FIXME: this would only be done in f_init_client(), but we need it before */
	rspro[0].rspro_client_slot := { clientId := 23+0, slotNr := 0 };

	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	f_rspro_srv_reset_state(ok);

	/* create slotmap */
	var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
	f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);

	f_sleep(1.0);

	/* connect client */
	f_init_client(0);
	f_rspro_connect_client(0, tr_Status_ok_or_nocard);
	/* FIXME: how to determine that bank correctly mapped us */

	/* re-create same mapping for the same bank-slot */
	f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);

	/* expect client not to be disconnected */
	timer T := 5.0;
	T.start;
	alt {
	[] RSPRO[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
		setverdict(fail, "Unexpected client disconnect");
		}
	[] RSPRO[0].receive {
		repeat;
		}
	[] T.timeout {
		setverdict(pass);
		}
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}



/* add mapping, connect matching client, disconnect + reconnect */
testcase TC_createMapping_clientReconnect() runs on bankd_test_CT {
	/* FIXME: this would only be done in f_init_client(), but we need it before */
	rspro[0].rspro_client_slot := { clientId := 23+0, slotNr := 0 };

	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	f_rspro_srv_reset_state(ok);

	var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
	f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);

	f_sleep(1.0);

	f_init_client(0);
	f_rspro_connect_client(0, tr_Status_ok_or_nocard);
	/* TODO: works only with empty slot, as setAtrReq isn't handled */
	/* FIXME: how to determine that bank correctly mapped us */
	f_sleep(5.0);
	f_rspro_fini(rspro[0], 0);

	f_init_client(0);
	f_rspro_connect_client(0, tr_Status_ok_or_nocard);
	/* FIXME: how to determine that bank correctly mapped us */
	f_sleep(5.0);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}



/* remove mapping while client is connected */
testcase TC_removeMapping_connected() runs on bankd_test_CT {
	f_init_client(0);
	f_rspro_connect_client(0, tr_Status_ok_or_nocard);
	/* TODO: works only with empty slot, as setAtrReq isn't handled */

	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);

	var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
	f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);
	/* FIXME: how to determine that bank correctly mapped us */
	f_sleep(5.0);
	f_rspro_srv_remove_slotmap(rspro[0].rspro_client_slot, bs);
	f_rspro_exp_disconnect(0);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}

private altstep as_vpcd() runs on VPCD_Adapter_CT {
	[] VPCD.receive(tr_VPCD_Recv(g_vpcd_conn_id, tr_VPCD_CTRL_ATR)) {
		f_vpcd_send(ts_VPCD_DATA('3B9F96801FC78031A073BE21136743200718000001A5'O));
		repeat;
		}
	[] VPCD.receive(tr_VPCD_Recv(g_vpcd_conn_id, tr_VPCD_CTRL_OFF)) {
		repeat;
		}
	[] VPCD.receive(tr_VPCD_Recv(g_vpcd_conn_id, tr_VPCD_CTRL_ON)) {
		repeat;
		}
}

/* transceive a TPDU from modem to card (and back) */
function f_rspro_xceive_mdm2card_vpcd(integer idx, BankSlot bs, template (value) octetstring data,
				 template (value) TpduFlags flags, template (value) octetstring res) runs on bankd_test_CT return octetstring {
	var RsproPDU rx;
	RSPRO[idx].send(ts_RSPRO_TpduModemToCard(rspro[idx].rspro_client_slot, bs, flags, data));
	f_vpcd_exp(tr_VPCD_DATA(data));
	f_vpcd_send(ts_VPCD_DATA(res));
	rx := f_rspro_exp(tr_RSPRO_TpduCardToModem(bs, rspro[idx].rspro_client_slot, ?, ?));
	if (rx.msg.tpduCardToModem.data != valueof(res)) {
		setverdict(fail, "Expected ", res, " from card, but got ", rx.msg.tpduCardToModem.data);
	}
	return rx.msg.tpduCardToModem.data;
}


/* first add mapping, then connect matching client and exchange some TPDUs */
testcase TC_createMapping_exchangeTPDU() runs on bankd_test_CT {
	/* FIXME: this would only be done in f_init_client(), but we need it before */
	rspro[0].rspro_client_slot := { clientId := 23+0, slotNr := 0 };

	VPCD_Adapter.f_connect();
	activate(as_vpcd());
	f_sleep(2.0);

	f_init();
	as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
	f_rspro_srv_reset_state(ok);

	var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
	f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);

	f_sleep(1.0);

	f_init_client(0);
	f_rspro_connect_client(0, ok);
	/* FIXME: how to determine that bank correctly mapped us */
	f_rspro_exp(tr_RSPRO_SetAtrReq(rspro[0].rspro_client_slot, ?));

	var TpduFlags f := {tpduHeaderPresent:=true, finalPart:=true, procByteContinueTx:=false,
			    procByteContinueRx:=false};
	for (var integer i := 0; i < 10; i:=i+1) {
		f_rspro_xceive_mdm2card_vpcd(0, bs, 'A0A40000023F00'O, f, '9000'O);
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}



control {
	execute( TC_connectBankReq_timeout() );
	execute( TC_connectBankReq() );

	execute( TC_createMapping() );
	execute( TC_createMapping_busySlot() );
	execute( TC_createMapping_invalidSlot() );
	execute( TC_createMapping_invalidBank() );

	execute( TC_removeMapping_unknownMap() );
	execute( TC_removeMapping() );

	execute( TC_clientConnect_missingSlot() );
	execute( TC_clientConnect_unknown() );
	execute( TC_clientConnect_createMapping() );
	execute( TC_createMapping_clientConnect() );
	execute( TC_createMapping_clientReconnect() );
	execute( TC_removeMapping_connected() );

	execute( TC_createMapping_connectClient_changeMapping() );
	execute( TC_createMapping_connectClient_recreateMapping() );

	execute( TC_createMapping_exchangeTPDU() );
}





}
