/* Simple / General implementation of an External USSD Entity using OsmoHLR's GSUP Protocol
 *
 * The idea is that a test case can simply start an instance of this component in parallel to its
 * normal test components.   HLR_EUSE_CT will then connect via GSUP to the HLR as the specified EUSE
 * name.  Any USSD related GSUP message received will be passed to a user-provided call-back
 * function, which will return whatever PDU to send in response back to the HLR.
 */


/* (C) 2018 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
 */

module HLR_EUSE {

import from GSUP_Types all;
import from GSUP_Templates all;
import from IPA_Emulation all;

import from General_Types all;
import from Osmocom_Types all;
import from SS_Types all;
import from SS_Templates all;

/* emulating an external USSD Entity towards OsmoHLR */
type component HLR_EUSE_CT {
	/* Component reference + config of underlying IPA emulation */
	var IPA_Emulation_CT vc_IPA_EUSE;
	var IPA_CCM_Parameters ccm_pars;
	/* port towards the underlying IPA emulation */
	port IPA_GSUP_PT EUSE;
}

private function f_init(charstring hlr_ip, uint16_t hlr_gsup_port, charstring name) runs on HLR_EUSE_CT {
	var charstring id := "EUSE-" & name;
	ccm_pars := c_IPA_default_ccm_pars;
	ccm_pars.name := "Osmocom TTCN-3 EUSE Simulator";
	ccm_pars.ser_nr := id;

	vc_IPA_EUSE := IPA_Emulation_CT.create("IPA-" & id);
	map(vc_IPA_EUSE:IPA_PORT, system:IPA_CODEC_PT);
	connect(vc_IPA_EUSE:IPA_GSUP_PORT, self:EUSE);
	vc_IPA_EUSE.start(IPA_Emulation.main_client(hlr_ip, hlr_gsup_port, "", 0, ccm_pars));

	timer T := 10.0;
	T.start;
	alt {
	[] EUSE.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { repeat; }
	[] EUSE.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) { }
	[] T.timeout {
		setverdict(fail, "EUSE: Timeout waiting for GSUP IPA Link to come up");
		self.stop;
		}
	}
}

type function f_euse_cb(GSUP_PDU rx_pdu) return GSUP_PDU;

function f_ss_echo_continue(GSUP_PDU rx_pdu) return GSUP_PDU {
	var GSUP_SessionState ss_next_state;
	var GSUP_IeValue ss_ie, state_ie;
	var SS_FacilityInformation dec_fac, rsp_fac;
	var octetstring ss_rsp;

	f_gsup_find_ie(rx_pdu, OSMO_GSUP_SESSION_STATE_IE, state_ie);
	var GSUP_SessionState ss_state := state_ie.session_state;

	f_gsup_find_ie(rx_pdu, OSMO_GSUP_SS_INFO_IE, ss_ie);
	dec_fac := dec_SS_FacilityInformation(ss_ie.ss_info);
	log("dec_fac: ", dec_fac);
	rsp_fac := valueof(ts_SS_USSD_FACILITY_RETURN_RESULT(dec_fac[0].invoke.invokeId.present_,
					SS_OP_CODE_PROCESS_USS_REQ,
					dec_fac[0].invoke.argument.uSSD_Arg.ussd_DataCodingScheme,
					dec_fac[0].invoke.argument.uSSD_Arg.ussd_String));
	ss_rsp := enc_SS_FacilityInformation(rsp_fac);
	select (ss_state) {
	case (OSMO_GSUP_SESSION_STATE_BEGIN) { ss_next_state := OSMO_GSUP_SESSION_STATE_CONTINUE; }
	case (OSMO_GSUP_SESSION_STATE_CONTINUE) { ss_next_state := OSMO_GSUP_SESSION_STATE_END; }
	}
	return valueof(ts_GSUP_PROC_SS_RES(rx_pdu.ies[0].val.imsi, rx_pdu.ies[1].val.session_id,
					   ss_next_state, ss_rsp));
}

function f_ss_echo(GSUP_PDU rx_pdu) return GSUP_PDU {
	var GSUP_IeValue ss_ie;
	var SS_FacilityInformation dec_fac, rsp_fac;
	var octetstring ss_rsp;

	f_gsup_find_ie(rx_pdu, OSMO_GSUP_SS_INFO_IE, ss_ie);
	dec_fac := dec_SS_FacilityInformation(ss_ie.ss_info);
	log("dec_fac: ", dec_fac);
	rsp_fac := valueof(ts_SS_USSD_FACILITY_RETURN_RESULT(dec_fac[0].invoke.invokeId.present_,
					SS_OP_CODE_PROCESS_USS_REQ,
					dec_fac[0].invoke.argument.uSSD_Arg.ussd_DataCodingScheme,
					dec_fac[0].invoke.argument.uSSD_Arg.ussd_String));
	ss_rsp := enc_SS_FacilityInformation(rsp_fac);
	return valueof(ts_GSUP_PROC_SS_RES(rx_pdu.ies[0].val.imsi, rx_pdu.ies[1].val.session_id,
					   OSMO_GSUP_SESSION_STATE_END, ss_rsp));
}

/* main function for handling mobile-originated USSD via GSUP */
function f_main_mo(charstring hlr_ip, uint16_t hlr_gsup_port, charstring name, f_euse_cb cb_fn)
runs on HLR_EUSE_CT {
	var GSUP_PDU rx_pdu, tx_pdu;

	f_init(hlr_ip, hlr_gsup_port, name);

	while (true) {
		alt {
		[] EUSE.receive(tr_GSUP_PROC_SS_REQ(?, ?, ?)) -> value rx_pdu {
			EUSE.send(cb_fn.apply(rx_pdu));
			}


		[] EUSE.receive {
			setverdict(fail, "EUSE: Unexpected Rx from HLR");
			self.stop;
			}
		}
	}
}


}
