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 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;

type component BSSAP_Adapter_CT {
	/* component references */
	var M3UA_CT vc_M3UA;
	var SCCP_CT vc_SCCP;
	/* test port to SCCP emulation */
	port BSSAP_CODEC_PT BSSAP;

	var octetstring g_sio;
	var MSC_SCCP_MTP3_parameters g_sccp_pars;
	var SCCP_PAR_Address g_sccp_addr_own, g_sccp_addr_peer;
}

modulepar {
	charstring mp_sccp_service_type := "mtp3_itu";

	SCTP_Association_Address mp_sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" };
	integer mp_own_pc := 185;	/* 0.23.1 */
	integer mp_own_ssn := 254;

	integer mp_peer_pc := 187;
	integer mp_peer_ssn := 254;
}

/* 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) := {
	addressIndicator := {
		pointCodeIndic := '1'B,
		ssnIndicator := '1'B,
		globalTitleIndic := '0000'B,
		routingIndicator := '1'B
	},
	signPointCode := SCCP_SPC_int2bit(pc, mp_sccp_service_type, '83'O),
	//signPointCode := SCCP_SPC_int2bit(pc, mp_sccp_service_type, g_sio),
	subsystemNumber := ssn,
	globalTitle := omit
}

private function init_pars() runs on BSSAP_Adapter_CT {
	g_sio := '83'O;
	g_sccp_pars := {
		sio := {
			ni := substr(oct2bit(g_sio),0,2),
			prio := substr(oct2bit(g_sio),2,2),
			si := substr(oct2bit(g_sio),4,4)
		},
		opc := mp_own_pc,
		dpc := mp_peer_pc,
		sls := 0,
		sccp_serviceType := mp_sccp_service_type,
		ssn := mp_own_ssn
	};
	g_sccp_addr_own := valueof(ts_SccpAddr_PC_SSN(mp_own_pc, mp_own_ssn));
	g_sccp_addr_peer := valueof(ts_SccpAddr_PC_SSN(mp_peer_pc, mp_peer_ssn));
}


function f_bssap_init(charstring id) runs on BSSAP_Adapter_CT
{
	init_pars();

	/* create components */
	vc_M3UA := M3UA_CT.create(id & "-M3UA");
	vc_SCCP := SCCP_CT.create(id & "-SCCP");

	map(vc_M3UA:SCTP_PORT, system:sctp);

	/* connect MTP3 service provider (M3UA) to lower side of SCCP */
	connect(vc_M3UA:MTP3_SP_PORT, vc_SCCP:MTP3_SCCP_PORT);

	/* connect BSSNAP dispatcher to upper side of SCCP */
	connect(self:BSSAP, vc_SCCP:SCCP_SP_PORT);

	vc_M3UA.start(f_M3UA_Emulation(mp_sctp_addr));
	vc_SCCP.start(SCCPStart(g_sccp_pars));
}

private altstep as_reset_ack() runs on BSSAP_Adapter_CT {
	var BSSAP_N_UNITDATA_ind ud_ind;
	[] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind {
		log("Respoding to inbound RESET with RESET-ACK");
		BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
			   ts_BSSMAP_ResetAck));
	}
}


function f_bssap_wait_for_reset() runs on BSSAP_Adapter_CT {
	var BSSAP_N_UNITDATA_ind ud_ind;
	timer T := 20.0;

	T.start;
	alt {
	[] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind {
		BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
			   ts_BSSMAP_ResetAck));
		}
	[] as_reset_ack();
	[] BSSAP.receive {
		repeat;
		}
	[] T.timeout {
		setverdict(fail);
		}
	}
}

function f_bssap_reset() runs on BSSAP_Adapter_CT {
	timer T := 5.0;

	BSSAP.send(ts_BSSAP_UNITDATA_req(g_sccp_addr_peer, g_sccp_addr_own, ts_BSSMAP_Reset(0)));
	T.start;
	alt {
	[] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_sccp_addr_own, g_sccp_addr_peer, tr_BSSMAP_ResetAck)) {
		log("Received RESET-ACK in response to RESET, we're ready to go!");
		}
	[] as_reset_ack();
	[] BSSAP.receive { repeat };
	[] T.timeout { setverdict(fail, "Waiting for RESET-ACK after sending RESET"); }
	}
}


}
