/* 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 by Harald Welte <laforge@gnumonks.org> */

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(ASP_IPA_Event:{up_down := ASP_IPA_EVENT_UP}) { repeat; }
	[] EUSE.receive(ASP_IPA_Event:{up_down := 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;
			}
		}
	}
}


}
