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 SCCPliste */
	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);
		ba.vc_IPA.start(IPA_Emulation.main_server(cfg.sctp_addr.local_ip_addr,
							cfg.sctp_addr.local_sctp_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);
		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));
		}
	case else {
		setverdict(fail, "Unsuppored BSSAP_Transport");
		self.stop;
		}
	}

	ba.vc_SCCP.start(SCCPStart(ba.sccp_pars));

	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 upposer side of SCCP */
		connect(ba.vc_BSSMAP:BSSAP, ba.vc_SCCP:SCCP_SP_PORT);
		/* start the BSSMAP emulation */
		ba.vc_BSSMAP.start(BSSMAP_Emulation.main(valueof(ops), ""));
	}
}


}
