module BSSAP_Adapter {

/* This module implements a 'dumb' BSSAP adapter.  It creates the M3UA and SCCP components and stacks a BSSAP
 * codec port on top.  As a result, it provides the ability to transceive SCCP-User-SAP primitives with
 * deoded BSSAP 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_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 SCTPasp_Types all;
import from SCTPasp_PortType all;

import from BSSAP_CodecPort all;
import from BSSMAP_Templates all;
import from BSSMAP_Emulation all;

type record BSSAP_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 */
	BSSMAP_Emulation_CT vc_BSSMAP
}

type enumerated BSSAP_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 BSSAP_Configuration {
	BSSAP_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
};

/* construct a SCCP_PAR_Address with just PC + SSN and no GT */
template (value) SCCP_PAR_Address ts_SccpAddr_PC_SSN(integer pc, integer ssn, octetstring sio,
							charstring sccp_srv_type) := {
	addressIndicator := {
		pointCodeIndic := '1'B,
		ssnIndicator := '1'B,
		globalTitleIndic := '0000'B,
		routingIndicator := '1'B
	},
	signPointCode := SCCP_SPC_int2bit(pc, sccp_srv_type, sio),
	subsystemNumber := ssn,
	globalTitle := omit
}

private function init_pars(inout BSSAP_Adapter ba, in BSSAP_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_bssap_init(inout BSSAP_Adapter ba, in BSSAP_Configuration cfg, charstring id,
			template BssmapOps 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_BSSMAP := BSSMAP_Emulation_CT.create(id & "-BSSMAP");
	}
	select (cfg.transport) {
	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));
		}
	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));
		/* 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);
		}
	case else {
		setverdict(fail, "Unsuppored BSSAP_Transport");
		self.stop;
		}
	}

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


}

function f_bssap_start(inout BSSAP_Adapter ba) {
	ba.vc_SCCP.start(SCCPStart(ba.sccp_pars));
}


}
