/* 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 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;
			}
		}
	}
}


}
