module RAN_Adapter {

/* This module implements a 'dumb' RAN adapter.  It creates the M3UA and SCCP components and stacks a
 * BSSAP/RANAP codec port on top.  As a result, it provides the ability to transceive SCCP-User-SAP primitives
 * with deoded BSSAP/RANAP payload.  Use this if you want to have full control about what you transmit or
 * receive, without any automatisms in place.  Allows you to refuse connections or other abnormal behavior. */

import from General_Types all;
import from Osmocom_Types all;

import from M3UA_Emulation all;
import from MTP3asp_Types all;
import from MTP3asp_PortType all;

import from IPA_Emulation all;

import from SCCP_Types all;
import from SCCPasp_Types all;
import from SCCP_Emulation all;
import from SCCP_Templates all;

import from SCTPasp_Types all;
import from SCTPasp_PortType all;

#ifdef RAN_EMULATION_BSSAP
import from BSSMAP_Templates all;
#endif
import from RAN_Emulation all;

type record RAN_Adapter {
	/* component references */
	M3UA_CT vc_M3UA,		/* only in 3GPP AoIP */
	IPA_Emulation_CT vc_IPA,	/* only in SCCPlite */
	IPA_EventWaiter_CT vc_WAIT,	/* only in SCCPlite */
	SCCP_CT vc_SCCP,

	MSC_SCCP_MTP3_parameters sccp_pars,
	SCCP_PAR_Address sccp_addr_own,
	SCCP_PAR_Address sccp_addr_peer,

	/* handler mode */
	RAN_Emulation_CT vc_RAN
}

type enumerated RAN_Transport {
	BSSAP_TRANSPORT_AoIP,	/* 3GPP AoIP: SCCP over M3UA over SCTP */
	BSSAP_TRANSPORT_SCCPlite_SERVER, /* SCCPlite: SCCP over IPA over TCP */
	BSSAP_TRANSPORT_SCCPlite_CLIENT  /* SCCPlite: SCCP over IPA over TCP */
};

type record RAN_Configuration {
	RAN_Transport transport,
	charstring sccp_service_type,
	SCTP_Association_Address sctp_addr,
	integer own_pc,
	integer own_ssn,
	integer peer_pc,
	integer peer_ssn,
	octetstring sio,
	integer rctx
};

private function init_pars(inout RAN_Adapter ba, in RAN_Configuration cfg) {
	ba.sccp_pars := {
		sio := {
			ni := substr(oct2bit(cfg.sio),0,2),
			prio := substr(oct2bit(cfg.sio),2,2),
			si := substr(oct2bit(cfg.sio),4,4)
		},
		opc := cfg.own_pc,
		dpc := cfg.peer_pc,
		sls := 0,
		sccp_serviceType := cfg.sccp_service_type,
		ssn := cfg.own_ssn
	};
	ba.sccp_addr_own := valueof(ts_SccpAddr_PC_SSN(cfg.own_pc, cfg.own_ssn, cfg.sio, cfg.sccp_service_type));
	ba.sccp_addr_peer := valueof(ts_SccpAddr_PC_SSN(cfg.peer_pc, cfg.peer_ssn, cfg.sio, cfg.sccp_service_type));
}


function f_ran_adapter_init(inout RAN_Adapter ba, in RAN_Configuration cfg, charstring id,
			template RanOps ops) {
	init_pars(ba, cfg);
	ops.sccp_addr_local := ba.sccp_addr_own;
	ops.sccp_addr_peer := ba.sccp_addr_peer;

	/* create components */
	ba.vc_SCCP := SCCP_CT.create(id & "-SCCP");
	if (isvalue(ops)) {
		ba.vc_RAN := RAN_Emulation_CT.create(id & "-RAN");
	}
	select (cfg.transport) {
#ifdef RAN_EMULATION_BSSAP
	case (BSSAP_TRANSPORT_AoIP) {
		ba.vc_M3UA := M3UA_CT.create(id & "-M3UA");
		map(ba.vc_M3UA:SCTP_PORT, system:sctp);
		/* connect MTP3 service provider (M3UA) to lower side of SCCP */
		connect(ba.vc_M3UA:MTP3_SP_PORT, ba.vc_SCCP:MTP3_SCCP_PORT);
		ba.vc_M3UA.start(f_M3UA_Emulation(cfg.sctp_addr, cfg.rctx));
		}
#ifdef IPA_EMULATION_SCCP
	case (BSSAP_TRANSPORT_SCCPlite_SERVER) {
		ba.vc_IPA := IPA_Emulation_CT.create(id & "-IPA");
		map(ba.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
		/* connect MTP3 service provider (IPA) to lower side of SCCP */
		connect(ba.vc_IPA:MTP3_SP_PORT, ba.vc_SCCP:MTP3_SCCP_PORT);
		/* connect waiter to general IPA port (for ASP_IPA_Event) */
		ba.vc_WAIT := IPA_EventWaiter_CT.create(id & "-IPA-WAIT");
		connect(ba.vc_IPA:IPA_SP_PORT, ba.vc_WAIT:IPA_SP_PORT);
		ba.vc_WAIT.start(IPA_Emulation.waiter_main());
		ba.vc_IPA.start(IPA_Emulation.main_server(cfg.sctp_addr.local_ip_addr,
							cfg.sctp_addr.local_sctp_port,
							true, IPA_INIT_SEND_IPA_ID_ACK));
		/* wait until we received an IPA CCM ID_ACK */
		ba.vc_WAIT.done;
		disconnect(ba.vc_IPA:IPA_SP_PORT, ba.vc_WAIT:IPA_SP_PORT);
		}
	case (BSSAP_TRANSPORT_SCCPlite_CLIENT) {
		ba.vc_IPA := IPA_Emulation_CT.create(id & "-IPA");
		map(ba.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
		/* connect MTP3 service provider (IPA) to lower side of SCCP */
		connect(ba.vc_IPA:MTP3_SP_PORT, ba.vc_SCCP:MTP3_SCCP_PORT);
		/* connect waiter to general IPA port (for ASP_IPA_Event) */
		ba.vc_WAIT := IPA_EventWaiter_CT.create(id & "-IPA-WAIT");
		connect(ba.vc_IPA:IPA_SP_PORT, ba.vc_WAIT:IPA_SP_PORT);
		ba.vc_WAIT.start(IPA_Emulation.waiter_main());
		ba.vc_IPA.start(IPA_Emulation.main_client(cfg.sctp_addr.remote_ip_addr,
							cfg.sctp_addr.remote_sctp_port,
							cfg.sctp_addr.local_ip_addr,
							cfg.sctp_addr.local_sctp_port));
		/* wait until we received an IPA CCM ID_ACK */
		ba.vc_WAIT.done;
		disconnect(ba.vc_IPA:IPA_SP_PORT, ba.vc_WAIT:IPA_SP_PORT);
		}
#endif /* SCCP */
#endif /* BSSAP */
	case else {
		setverdict(fail, "Unsuppored RAN_Transport");
		mtc.stop;
		}
	}

	if (isvalue(ops)) {
		timer T := 5.0;
		T.start;
		//T.timeout;
		log("Connecting BSSMAP Emulation to SCCP_SP_PORT and starting emulation");
#if RAN_EMULATION_BSSAP
		/* connect BSSNAP component to upper side of SCCP */
		connect(ba.vc_RAN:BSSAP, ba.vc_SCCP:SCCP_SP_PORT);
#endif
		if (cfg.transport == BSSAP_TRANSPORT_SCCPlite_SERVER or
		    cfg.transport == BSSAP_TRANSPORT_SCCPlite_CLIENT) {
#ifdef IPA_EMULATION_MGCP
			/* connect IPA MGCP port with BSSMAP MGCP port */
			connect(ba.vc_IPA:IPA_MGCP_PORT, ba.vc_RAN:MGCP);
#endif
		}
		/* start the BSSMAP emulation */
		ba.vc_RAN.start(RAN_Emulation.main(valueof(ops), ""));
	}


}

function f_ran_adapter_start(inout RAN_Adapter ba) {
	ba.vc_SCCP.start(SCCPStart(ba.sccp_pars));
}


}
