module SIP_Tests {

import from General_Types all;
import from Osmocom_Types all;

import from Osmocom_CTRL_Functions all;
import from Osmocom_CTRL_Types all;
import from Osmocom_CTRL_Adapter all;

import from TELNETasp_PortType all;
import from Osmocom_VTY_Functions all;

import from MNCC_Emulation all;
import from MNCC_Types all;

import from SDP_Types all;

import from SIP_Emulation all;
import from SIPmsg_Types all;
import from SIP_Templates all;

modulepar {
	charstring mp_local_host := "127.0.0.2";
	charstring mp_osmosip_host := "127.0.0.1";
	integer mp_osmosip_port_ctrl := -1; /* RFU */
	charstring mp_mncc := "/tmp/mncc";
}

type component test_CT extends CTRL_Adapter_CT {
	var MNCC_Emulation_CT vc_MNCC;
	var SIP_Emulation_CT vc_SIP;

	port TELNETasp_PT SIPVTY;
}

type component ConnHdlr extends SIP_ConnHdlr, MNCC_ConnHdlr {
	var ConnHdlrPars g_pars;
	timer g_Tguard;
}

type record ConnHdlrPars {
	float t_guard,
	CallPars g_cp optional
}

type record CallPars {
	boolean is_mo,
	charstring calling,
	charstring called,

	uint32_t mncc_call_id optional,

	CallParsComputed comp optional
}

type record CallParsComputed {
	CallidString sip_call_id,
	SipAddr sip_url_ext,
	SipAddr sip_url_gsm,
	charstring sip_body,
	integer sip_seq_nr
}

private template (value) CallPars t_CallPars(boolean is_mo) := {
	is_mo := is_mo,
	calling := "12345",
	called := "98766",
	mncc_call_id := omit,
	comp := omit
}

private function f_CallPars_compute(inout CallPars cp) {
	if (cp.is_mo) {
		cp.comp.sip_url_ext := valueof(ts_SipAddr(cp.called, mp_local_host, 5060));
		cp.comp.sip_url_gsm := valueof(ts_SipAddr(cp.calling, mp_osmosip_host, 5060));
		cp.mncc_call_id := f_rnd_int(429496725);
	} else {
		cp.comp.sip_url_ext := valueof(ts_SipAddr(cp.calling, mp_local_host, 5060));
		cp.comp.sip_url_gsm := valueof(ts_SipAddr(cp.called, mp_osmosip_host, 5060));
		cp.comp.sip_call_id := hex2str(f_rnd_hexstring(15));
	}
	cp.comp.sip_seq_nr := f_rnd_int(4294967295);
	cp.comp.sip_body := "";
}


function f_init_mncc(charstring id) runs on test_CT {
	id := id & "-MNCC";
	var MnccOps ops := {
		create_cb := refers(MNCC_Emulation.ExpectedCreateCallback),
		unitdata_cb := refers(MNCC_Emulation.DummyUnitdataCallback)
	};

	vc_MNCC := MNCC_Emulation_CT.create(id);
	map(vc_MNCC:MNCC, system:MNCC_CODEC_PT);
	vc_MNCC.start(MNCC_Emulation.main(ops, id, mp_mncc, true));
}

function f_init() runs on test_CT {
	//f_ipa_ctrl_start(mp_osmosip_host, mp_osmosip_port_ctrl);
	f_init_mncc("SIP_Test");
	log("end of f_init_mncc");
	f_init_sip(vc_SIP, "SIP_Test");
	log("end of f_init_sip");

	map(self:SIPVTY, system:SIPVTY);
	f_vty_set_prompts(SIPVTY);
	f_vty_transceive(SIPVTY, "enable");
	log("end of f_init");
}

type function void_fn(charstring id) runs on ConnHdlr;

function f_start_handler(void_fn fn, ConnHdlrPars pars)
runs on test_CT return ConnHdlr {
	var ConnHdlr vc_conn;
	var charstring id := testcasename();

	vc_conn := ConnHdlr.create(id);

	connect(vc_conn:SIP, vc_SIP:CLIENT);
	connect(vc_conn:SIP_PROC, vc_SIP:CLIENT_PROC);

	connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT);
	connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC);

	vc_conn.start(f_handler_init(fn, id, pars));
	return vc_conn;
}

private altstep as_Tguard() runs on ConnHdlr {
	[] g_Tguard.timeout {
		setverdict(fail, "Tguard timeout");
		self.stop;
	}
}

private function f_handler_init(void_fn fn, charstring id, ConnHdlrPars pars)
runs on ConnHdlr {
	g_pars := pars;
	g_Tguard.start(pars.t_guard);
	activate(as_Tguard());

	/* call the user-supied test case function */
	fn.apply(id);
}


template (value) ConnHdlrPars t_Pars := {
	t_guard := 30.0,
	g_cp := omit
}

/* Establish a mobile terminated call described in 'cp' */
function f_establish_mt(inout CallPars cp) runs on ConnHdlr {
	var template SipAddr sip_addr_gsm := tr_SipAddr_from_val(cp.comp.sip_url_gsm);
	var template SipAddr sip_addr_ext := tr_SipAddr_from_val(cp.comp.sip_url_ext);
	var PDU_SIP_Request sip_req;
	var MNCC_PDU mncc;

	/* Ask MNCC_Emulation to "expect" a call to the given called number */
	f_create_mncc_expect(cp.called);

	/* OSC <- SIP: A party sends SIP invite for a MT-call into OSC */
	SIP.send(ts_SIP_INVITE(cp.comp.sip_call_id, cp.comp.sip_url_ext, cp.comp.sip_url_gsm,
				cp.comp.sip_seq_nr, cp.comp.sip_body));
	/* MSC <- OSC: OSC generates MNCC_SETUP_REQ from INVITE */
	MNCC.receive(tr_MNCC_SETUP_req) -> value mncc {
		cp.mncc_call_id := mncc.u.signal.callref;
		}
	/* OSC -> SIP */
	SIP.receive(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, sip_addr_gsm, *,
				    "INVITE", 100, ?, "Trying", *));

	/* MSC -> OSC: After MS sends CALL CONF in response to SETUP */
	MNCC.send(ts_MNCC_CALL_CONF_ind(cp.mncc_call_id));
	/* MSC <- OSC: OSC asks MSC to create RTP socket */
	MNCC.receive(tr_MNCC_RTP_CREATE(cp.mncc_call_id));
	MNCC.send(ts_MNCC_RTP_CREATE(cp.mncc_call_id));

	/* MSC -> OSC: After MS is ringing and sent CC ALERTING */
	MNCC.send(ts_MNCC_ALERT_ind(cp.mncc_call_id));
	SIP.clear;
	SIP.receive(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, sip_addr_gsm, *,
				    "INVITE", 180, ?, "Ringing", *));

	/* MSC -> OSC: After MT user has picked up and sent CC CONNECT */
	MNCC.send(ts_MNCC_SETUP_CNF(cp.mncc_call_id));

	SIP.clear;
	interleave {
	/* MSC <- OSC: OSC asks MSC to connect its RTP stream to remote end */
	[] MNCC.receive(tr_MNCC_RTP_CONNECT(cp.mncc_call_id)) {}
	/* OSC -> SIP: OSC confirms call establishment to SIP side */
	[] SIP.receive(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, sip_addr_gsm, ?,
					"INVITE", 200, ?, "OK", ?)) {}
	}
	/* OSC <- SIP: SIP world acknowledges "200 OK" */
	SIP.send(ts_SIP_ACK(cp.comp.sip_call_id, cp.comp.sip_url_ext, cp.comp.sip_url_gsm,
			    cp.comp.sip_seq_nr, omit));
	/* MSC <- OSC: OSC sends SETUP COMPL to MNCC (which triggers CC CONNECT ACK */
	MNCC.receive(tr_MNCC_SETUP_COMPL_req(cp.mncc_call_id));
}

/* Establish a mobile originated call described in 'cp' */
function f_establish_mo(inout CallPars cp) runs on ConnHdlr {
	var MNCC_number dst := valueof(ts_MNCC_number(cp.called, GSM48_TON_UNKNOWN));
	var MNCC_number src := valueof(ts_MNCC_number(cp.calling, GSM48_TON_UNKNOWN));
	var template SipAddr sip_addr_gsm := tr_SipAddr_from_val(cp.comp.sip_url_gsm);
	var template SipAddr sip_addr_ext := tr_SipAddr_from_val(cp.comp.sip_url_ext);
	var PDU_SIP_Request sip_req;
	var integer seq_nr;

	f_create_sip_expect(cp.comp.sip_url_ext.addr.nameAddr.addrSpec);

	/* MSC -> OSC: MSC sends SETUP.ind after CC SETUP was received from MS */
	MNCC.send(ts_MNCC_SETUP_ind(cp.mncc_call_id, dst, src, "262420123456789"));
	/* MSC <- OSC: Create GSM side RTP socket */
	MNCC.receive(tr_MNCC_RTP_CREATE(cp.mncc_call_id)) {
		var MNCC_PDU mncc := valueof(ts_MNCC_RTP_CREATE(cp.mncc_call_id));
		mncc.u.rtp.payload_msg_type := oct2int('0300'O);
		MNCC.send(mncc);	/* FIXME: port/ip */
		}
	/* OSC -> SIP: Send INVITE with GSM side IP/Port in SDP */
	SIP.receive(tr_SIP_INVITE(?, sip_addr_gsm, sip_addr_ext, ?, ?)) -> value sip_req {
		cp.comp.sip_url_gsm.params := sip_req.msgHeader.fromField.fromParams;
		cp.comp.sip_call_id := sip_req.msgHeader.callId.callid;
		seq_nr := sip_req.msgHeader.cSeq.seqNumber;
		}
	/* OSC <- SIP: Notify call is proceeding */
	SIP.send(ts_SIP_Response(cp.comp.sip_call_id, cp.comp.sip_url_gsm, cp.comp.sip_url_ext,
				 "INVITE", 100, seq_nr, "Trying", sip_req.msgHeader.via));
	/* MSC <- OSC: "100 Trying" translated to MNCC_CALL_PROC_REQ */
	MNCC.receive(tr_MNCC_CALL_PROC_req(cp.mncc_call_id));

	/* OSC <- SIP: SIP-terminated user is ringing now */
	SIP.send(ts_SIP_Response(cp.comp.sip_call_id, cp.comp.sip_url_gsm, cp.comp.sip_url_ext,
				 "INVITE", 180, seq_nr, "Ringing", sip_req.msgHeader.via));

	/* MSC <- OSC: "180 Ringing" translated to MNCC_ALERT_REQ */
	MNCC.receive(tr_MNCC_ALERT_req(cp.mncc_call_id)) {}

	/* OSC <- SIP: SIP-terminated user has accepted the call */
	SIP.send(ts_SIP_Response(cp.comp.sip_call_id, cp.comp.sip_url_gsm, cp.comp.sip_url_ext,
				 "INVITE", 200, seq_nr, "OK", sip_req.msgHeader.via,
				 cp.comp.sip_body));
	MNCC.receive(tr_MNCC_RTP_CONNECT(cp.mncc_call_id));
	/* MSC <- OSC: "200 OK" translated to MNCC_SETUP_RSP */
	MNCC.receive(tr_MNCC_SETUP_rsp(cp.mncc_call_id));

	/* MSC -> OSC: CC CONNECT ACK was received from MS */
	MNCC.send(ts_MNCC_SETUP_COMPL_ind(cp.mncc_call_id));
	/* OSC -> SIP: Acknowledge the call */
	SIP.receive(tr_SIP_ACK(cp.comp.sip_call_id, sip_addr_gsm, sip_addr_ext, ?, omit));
}

/* Release call from the mobile side */
function f_release_mobile(inout CallPars cp) runs on ConnHdlr {
	var template SipAddr sip_addr_gsm := tr_SipAddr_from_val(cp.comp.sip_url_gsm);
	var template SipAddr sip_addr_ext := tr_SipAddr_from_val(cp.comp.sip_url_ext);
	var PDU_SIP_Request sip_req;
	SIP.clear;
	/* MSC -> OSC: Simulate a CC DISCONNET from the MT user */
	MNCC.send(ts_MNCC_DISC_ind(cp.mncc_call_id, ts_MNCC_cause(0)));
	/* OSC -> SIP: Expect BYE from OSC to SIP side */
	SIP.receive(tr_SIP_BYE(cp.comp.sip_call_id, sip_addr_gsm, sip_addr_ext, ?, *)) -> value sip_req {
		cp.comp.sip_url_gsm.params := sip_req.msgHeader.fromField.fromParams;
	}
	/* OSC <- SIP: Acknowledge the BYE */
	SIP.send(ts_SIP_Response(cp.comp.sip_call_id, cp.comp.sip_url_gsm, cp.comp.sip_url_ext,
					 "BYE", 200, sip_req.msgHeader.cSeq.seqNumber, "OK",
					 sip_req.msgHeader.via));
	/* MSC <- OSC: Send REL_REQ to MSC, triggers CC RELEASE REQ to MS */
	MNCC.receive(tr_MNCC_REL_req(cp.mncc_call_id)); // CAUSE?
	/* MSC -> OSC: MS has responded with CC CLEAR COMPL, triggers MNCC_REL_CNF */
	MNCC.send(ts_MNCC_REL_cnf(cp.mncc_call_id, ts_MNCC_cause(0)));
}

/* Release call from the SIP side */
function f_release_sip(inout CallPars cp) runs on ConnHdlr {
	var template SipAddr sip_addr_gsm := tr_SipAddr_from_val(cp.comp.sip_url_gsm);
	var template SipAddr sip_addr_ext := tr_SipAddr_from_val(cp.comp.sip_url_ext);
	/* OSC <- SIP: SIP-side sends a BYE to OSC */
	SIP.send(ts_SIP_BYE(cp.comp.sip_call_id, cp.comp.sip_url_ext, cp.comp.sip_url_gsm,
			    cp.comp.sip_seq_nr, omit));
	/* MSC <- OSC: Expect OSC to cause MNCC Disconnect Request */
	MNCC.receive(tr_MNCC_DISC_req(cp.mncc_call_id));
	/* MSC -> OSC: Indicate GSM side release */
	MNCC.send(ts_MNCC_REL_ind(cp.mncc_call_id, ts_MNCC_cause(0)));
	/* OSC -> SIP: Confirmation to SIP side */
	SIP.receive(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, sip_addr_gsm, *,
				    "BYE", 200, cp.comp.sip_seq_nr, "OK", omit));
}

/* Successful MT Call, which is subsequently released by GSM side */
private function f_TC_mt_success_rel_gsm(charstring id) runs on ConnHdlr {
	var CallPars cp := valueof(t_CallPars(false));
	f_CallPars_compute(cp);
	cp.comp.sip_body := "v=0\r\no=Osmocom 0 0 IN IP4 0.0.0.0\r\ns=GSM Call\r\nc=IN IP4 0.0.0.0\r\nt=0 0\r\nm=audio 0 RTP/AVP 0\r\na=rtpmap:0 GSM/8000\r\n";
	f_sleep(3.0)

	f_establish_mt(cp);
	/* now call is fully established */
	f_sleep(2.0);
	f_release_mobile(cp);
	setverdict(pass);
}
testcase TC_mt_success_rel_gsm() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();
	pars := valueof(t_Pars);
	vc_conn := f_start_handler(refers(f_TC_mt_success_rel_gsm), pars);
	vc_conn.done;
}

/* Successful MT Call, which is subsequently released by SIP side */
private function f_TC_mt_success_rel_sip(charstring id) runs on ConnHdlr {
	var CallPars cp := valueof(t_CallPars(false));
	f_CallPars_compute(cp);
	cp.comp.sip_body := "v=0\r\no=Osmocom 0 0 IN IP4 0.0.0.0\r\ns=GSM Call\r\nc=IN IP4 0.0.0.0\r\nt=0 0\r\nm=audio 0 RTP/AVP 0\r\na=rtpmap:0 GSM/8000\r\n";
	f_sleep(3.0)

	f_establish_mt(cp);
	/* now call is fully established */
	f_sleep(2.0);
	f_release_sip(cp);
	setverdict(pass);
}
testcase TC_mt_success_rel_sip() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();
	pars := valueof(t_Pars);
	vc_conn := f_start_handler(refers(f_TC_mt_success_rel_sip), pars);
	vc_conn.done;
}


/* Successful MO Call, which is subsequently released by GSM side */
private function f_TC_mo_success_rel_gsm(charstring id) runs on ConnHdlr {
	var CallPars cp := valueof(t_CallPars(true));
	f_CallPars_compute(cp);
	cp.comp.sip_body := "v=0\r\no=Osmocom 0 0 IN IP4 0.0.0.0\r\ns=GSM Call\r\nc=IN IP4 0.0.0.0\r\nt=0 0\r\nm=audio 0 RTP/AVP 0\r\na=rtpmap:0 GSM/8000\r\n";
	f_sleep(3.0)

	f_establish_mo(cp);
	/* now call is fully established */
	f_sleep(2.0);
	f_release_mobile(cp);
	setverdict(pass);
}
testcase TC_mo_success_rel_gsm() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();
	pars := valueof(t_Pars);
	vc_conn := f_start_handler(refers(f_TC_mo_success_rel_gsm), pars);
	vc_conn.done;
}

/* Successful MO Call, which is subsequently released by SIP side */
private function f_TC_mo_success_rel_sip(charstring id) runs on ConnHdlr {
	var CallPars cp := valueof(t_CallPars(true));
	f_CallPars_compute(cp);
	cp.comp.sip_body := "v=0\r\no=Osmocom 0 0 IN IP4 0.0.0.0\r\ns=GSM Call\r\nc=IN IP4 0.0.0.0\r\nt=0 0\r\nm=audio 0 RTP/AVP 0\r\na=rtpmap:0 GSM/8000\r\n";
	f_sleep(3.0)

	f_establish_mo(cp);
	/* now call is fully established */
	f_sleep(2.0);
	f_release_sip(cp);
	setverdict(pass);
}
testcase TC_mo_success_rel_sip() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();
	pars := valueof(t_Pars);
	vc_conn := f_start_handler(refers(f_TC_mo_success_rel_sip), pars);
	vc_conn.done;
}


control {
	execute( TC_mt_success_rel_gsm() );
	execute( TC_mt_success_rel_sip() );
	execute( TC_mo_success_rel_gsm() );
	execute( TC_mo_success_rel_sip() );
}



}
