/* GPRS-NS Emulation in TTCN-3
 * (C) 2018-2021 Harald Welte <laforge@gnumonks.org>
 * contributions by sysmocom - s.f.m.c. GmbH
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

module NS_Emulation {
	import from Misc_Helpers all;
	import from NS_Types all;
	import from BSSGP_Types all;
	import from Osmocom_Types all;
	import from Osmocom_Gb_Types all;
	import from NS_Provider_IPL4 all;
#ifdef NS_EMULATION_FR
	import from NS_Provider_FR all;
#endif
	import from IPL4asp_Types all;

	type record NsUnitdataRequest {
		BssgpBvci	bvci,
		Nsei		nsei,
		integer		lsp,
		octetstring	sdu optional,
		PDU_BSSGP	bssgp optional
	}

	template NsUnitdataRequest tr_NsUdReq(template Nsei nsei, template BssgpBvci bvci, template integer lsp,
					      template octetstring sdu, template PDU_BSSGP bssgp) := {
		bvci := bvci,
		nsei := nsei,
		lsp := lsp,
		sdu := sdu,
		bssgp := bssgp
	}

	template (value) NsUnitdataRequest ts_NsUdReq(template (value) Nsei nsei,
						      template (value) BssgpBvci bvci,
						      template (value) integer lsp,
						      template (omit) octetstring sdu,
						      template (omit) PDU_BSSGP bssgp) := {
		bvci := bvci,
		nsei := nsei,
		lsp := lsp,
		sdu := sdu,
		bssgp := bssgp
	}

	type record NsUnitdataIndication {
		BssgpBvci	bvci,
		Nsei		nsei,
		Nsvci		nsvci,
		octetstring	sdu optional,
		PDU_BSSGP	bssgp optional
	}

	template (present) NsUnitdataIndication tr_NsUdInd(template (present) Nsei nsei,
							   template (present) BssgpBvci bvci,
							   template octetstring sdu) := {
		bvci := bvci,
		nsei := nsei,
		nsvci := ?,
		sdu := sdu,
		bssgp := ?
	}

	template (value) NsUnitdataIndication ts_NsUdInd(Nsei nsei, Nsvci nsvci, BssgpBvci bvci, octetstring sdu) := {
		bvci := bvci,
		nsei := nsei,
		nsvci := nsvci,
		sdu := sdu,
		bssgp := dec_PDU_BSSGP(sdu)
	}

	type record NsStatusIndication {
		Nsei		nsei,
		Nsvci		nsvci,
		NsvcState	old_state,
		NsvcState	new_state,
		boolean		first_or_last
	}

	template (present) NsStatusIndication tr_NsStsInd(template (present) Nsei nsei := ?,
							  template (present) Nsvci nsvci := ?,
							  template (present) NsvcState old_state := ?,
							  template (present) NsvcState state := ?,
							  template (present) boolean first_or_last := ?) := {
		nsei := nsei,
		nsvci := nsvci,
		old_state := old_state,
		new_state := state,
		first_or_last := first_or_last
	}


	template (value) NsStatusIndication ts_NsStsInd(Nsei nsei, Nsvci nsvci, NsvcState old_state, NsvcState state,
							boolean first_or_last := false) := {
		nsei := nsei,
		nsvci := nsvci,
		old_state := old_state,
		new_state := state,
		first_or_last := first_or_last
	}

	type enumerated NsvcState {
		NSVC_S_DEAD_BLOCKED,
		NSVC_S_WAIT_RESET,
		NSVC_S_ALIVE_BLOCKED,
		NSVC_S_ALIVE_UNBLOCKED
	}

	/* port from our (internal) point of view */
	type port NS_SP_PT message {
		in	NsUnitdataRequest;
		out	NsUnitdataIndication,
			NsStatusIndication;
	} with { extension "internal" };

	/* port from the user point of view */
	type port NS_PT message {
		in	ASP_Event,
			NsStatusIndication,
			NsUnitdataIndication;
		out	NsUnitdataRequest;
	} with { extension "internal" };

	type component NS_Provider_CT {
		/* upper port, facing to NS_Emulation:NSCP */
		port NS_PROVIDER_PT NSE;
		/* lower layer ports (UDP/IP, Frame Relay) are added in derived components */
	};

	type enumerated NS_Provider_LinkStatus {
		NS_PROV_LINK_STATUS_UP,
		NS_PROV_LINK_STATUS_DOWN
	};
	type union NS_Provider_Evt {
		NS_Provider_LinkStatus link_status
	};

	/* port between NS_Provider and NS_CT */
	type port NS_PROVIDER_PT message {
		inout PDU_NS, NS_Provider_Evt;
	} with { extension "internal" };

	type record NSVCConfigurationIP {
		AddressFamily address_family,
		PortNumber local_udp_port,
		charstring local_ip,
		PortNumber remote_udp_port,
		charstring remote_ip,
		uint8_t data_weight,
		uint8_t signalling_weight
	};
	type record NSVCConfigurationFR {
		charstring netdev,	/* HDLC net-device for AF_PACKET socket */
		integer dlci
	};
	type union NSVCConfigurationP {
		NSVCConfigurationIP ip,
		NSVCConfigurationFR fr
	};
	type record NSVCConfiguration {
		NSVCConfigurationP provider,
		Nsvci nsvci
	};
	type record of NSVCConfiguration NSVCConfigurations;
	type record NSConfiguration {
		Nsvci nsei,
		boolean role_sgsn,
		boolean handle_sns,
		NSVCConfigurations nsvc
	}

	/***********************************************************************
	 * per NS-VCG component. Exists once per [peer of] NSE
	 ***********************************************************************/

	type component NS_CT {
		/* NS-User SAP towards the user */
		port NS_SP_PT NS_SP;

		/* port towards the per-NSVC components */
		port NSint_PT NSVC;

		/* all of the NS configuration a user passes to us */
		var NSConfiguration g_config;
		var charstring g_id;

		/* references to the per-NSVC components */
		var NsvcTable g_nsvcs := {};
		/* list of indexes to g_nsvcs[] of currently unblocked NSVCs */
		var ro_integer g_unblocked_nsvcs_sig := {};
		var ro_integer g_unblocked_nsvcs_data := {};
	};
	type record NsvcTableEntry {
		NSVCConfiguration cfg,
		NSVC_CT vc_conn,
		NsvcState state
	};
	type record of NsvcTableEntry NsvcTable;
	type record of integer ro_integer;

	/* internal port from the NS-VC point of view */
	type port NSint_SP_PT message {
		in	NsUnitdataRequest,
			SnsRequest,
			NsCtrlRequest;
		out	NsUnitdataIndication,
			SnsIndication,
			NsStatusIndication;
	} with { extension "internal" };

	/* internal port from the NS-VCG point of view */
	type port NSint_PT message {
		in	ASP_Event,
			NsStatusIndication,
			SnsIndication,
			NsUnitdataIndication;
		out	NsUnitdataRequest,
			SnsRequest,
			NsCtrlRequest;
	} with { extension "internal" };

	/* Used by NS-VC to report reception of a SNS PDU to NS-VCG */
	type record SnsIndication {
		Nsvci		nsvci,
		PDU_NS		ns
	};

	/* Used by NS-VCG to request transmission of a SNS PDU via a NS-VC */
	type record SnsRequest {
		Nsvci		nsvci,
		PDU_NS		ns
	};

	type enumerated NsCtrlRequest {
		StartAliveProcedure	(0)
	};

	/* add one NSVC (component and table entry */
	function f_nsvc_add(NSVCConfiguration nsvc_cfg) runs on NS_CT {
		var charstring nsvc_id := g_id & "-NSVCI" & int2str(nsvc_cfg.nsvci);
		var NsvcTableEntry te;

		te.cfg := nsvc_cfg;
		te.vc_conn := NSVC_CT.create(nsvc_id);
		te.state := NSVC_S_DEAD_BLOCKED;

		connect(self:NSVC, te.vc_conn:NS_SP);
		te.vc_conn.start(NSVCStart(nsvc_cfg, g_config, nsvc_id));

		g_nsvcs := g_nsvcs & { te };
		/* no need to add to g_unblocked_nsvcs, as state is always DEAD_BLOCKED above */
	}

	function f_nsvc_find_idx(Nsvci nsvci) runs on NS_CT return integer {
		var integer i;
		for (i := 0; i < lengthof(g_nsvcs); i := i+1) {
			if (g_nsvcs[i].cfg.nsvci == nsvci) {
				return i;
			}
		}
		return -1;
	}

	function f_nsvc_find(Nsvci nsvci) runs on NS_CT return NSVC_CT {
		var integer i := f_nsvc_find_idx(nsvci);
		if (i < 0) {
			return null;
		} else {
			return g_nsvcs[i].vc_conn;
		}
	}

	function f_nsvc_update_state(Nsvci nsvci, NsvcState state) runs on NS_CT {
		var integer i := f_nsvc_find_idx(nsvci);
		if (i < 0) {
			return;
		}
		if (g_nsvcs[i].state != NSVC_S_ALIVE_UNBLOCKED and state == NSVC_S_ALIVE_UNBLOCKED) {
			/* add index to list of unblocked NSVCs */
			if (not ischosen(g_nsvcs[i].cfg.provider.ip) or
			    g_nsvcs[i].cfg.provider.ip.signalling_weight > 0) {
				g_unblocked_nsvcs_sig := g_unblocked_nsvcs_sig & {i};
			}
			if (not ischosen(g_nsvcs[i].cfg.provider.ip) or
			    g_nsvcs[i].cfg.provider.ip.data_weight > 0) {
				g_unblocked_nsvcs_data := g_unblocked_nsvcs_data & {i};
			}
		} else if (g_nsvcs[i].state == NSVC_S_ALIVE_UNBLOCKED and state != NSVC_S_ALIVE_UNBLOCKED) {
			/* remove index to list of unblocked NSVCs */
			var ro_integer new_unblocked_nsvcs_sig := {};
			for (var integer j := 0; j < lengthof(g_unblocked_nsvcs_sig); j := j+1) {
				if (g_unblocked_nsvcs_sig[j] != i) {
					new_unblocked_nsvcs_sig := new_unblocked_nsvcs_sig & {j};
				}
			}
			g_unblocked_nsvcs_sig := new_unblocked_nsvcs_sig;

			var ro_integer new_unblocked_nsvcs_data := {};
			for (var integer j := 0; j < lengthof(g_unblocked_nsvcs_data); j := j+1) {
				if (g_unblocked_nsvcs_data[j] != i) {
					new_unblocked_nsvcs_data := new_unblocked_nsvcs_data & {j};
				}
			}
			g_unblocked_nsvcs_data := new_unblocked_nsvcs_data;

		}
		g_nsvcs[i].state := state;
	}

	function NSStart(NSConfiguration init_config, charstring id := testcasename()) runs on NS_CT {
		g_config := init_config;
		g_id := id;

		/* iterate over list of NS-VCs and start per-NSVC components */
		for (var integer i := 0; i < lengthof(g_config.nsvc); i := i+1) {
			var NSVCConfiguration nsvc_cfg := g_config.nsvc[i];
			f_nsvc_add(nsvc_cfg);
		}

		while (true) {
			alt {
			[] as_ns_common() {}
			}
		}
	}

	function f_count_nsvcs_in_state(template NsvcState state := ?) runs on NS_CT return integer {
		var integer i;
		var integer res := 0;
		for (i := 0; i < lengthof(g_nsvcs); i := i+1) {
			if (match(g_nsvcs[i].state, state)) {
				res := res + 1;
			}
		}
		return res;
	}

	private altstep as_ns_common() runs on NS_CT {
		var NsStatusIndication rx_nssi;
		var NsUnitdataIndication rx_nsudi;
		var NsUnitdataRequest rx_nsudr;
		/* pass from NS-VCs up to user */
		[] NSVC.receive(tr_NsStsInd(g_config.nsei, ?, ?, NSVC_S_ALIVE_UNBLOCKED)) -> value rx_nssi {
			/* check if this one is the first to be unblocked */
			var integer num_nsvc_unblocked := f_count_nsvcs_in_state(NSVC_S_ALIVE_UNBLOCKED);
			f_nsvc_update_state(rx_nssi.nsvci, rx_nssi.new_state);
			if (num_nsvc_unblocked == 0) {
				rx_nssi.first_or_last := true;
			}
			NS_SP.send(rx_nssi);
			}
		[] NSVC.receive(tr_NsStsInd(g_config.nsei, ?, ?, NSVC_S_DEAD_BLOCKED)) -> value rx_nssi {
			f_nsvc_update_state(rx_nssi.nsvci, rx_nssi.new_state);
			/* check if this one is the last to be blocked */
			var integer num_nsvc_unblocked := f_count_nsvcs_in_state(NSVC_S_ALIVE_UNBLOCKED);
			if (num_nsvc_unblocked == 0) {
				rx_nssi.first_or_last := true;
			}
			NS_SP.send(rx_nssi);
			}
		[] NSVC.receive(tr_NsStsInd(g_config.nsei, ?, ?, ?)) -> value rx_nssi {
			f_nsvc_update_state(rx_nssi.nsvci, rx_nssi.new_state);
			NS_SP.send(rx_nssi);
			}
		[] NSVC.receive(tr_NsStsInd) -> value rx_nssi {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("Received NsStatusInd for invalid NSEI: ", rx_nssi));
			}
		[] NSVC.receive(tr_NsUdInd(g_config.nsei, ?, ?)) -> value rx_nsudi {
			NS_SP.send(rx_nsudi);
			}

		[g_config.handle_sns and g_config.role_sgsn] as_vcg_sns_sgsn();

		[] NSVC.receive(tr_NsUdInd(?, ?, ?)) -> value rx_nsudi {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("Received UnitDataInd for invalid NSEI: ", rx_nsudi));
			}
		/* from user down to NS-VC */
		[] NS_SP.receive(tr_NsUdReq(g_config.nsei, 0, ?, ?, *)) -> value rx_nsudr {
			/* load distribution function */
			var integer nsvc_idx := g_unblocked_nsvcs_sig[rx_nsudr.lsp mod lengthof(g_unblocked_nsvcs_sig)];
			NSVC.send(rx_nsudr) to g_nsvcs[nsvc_idx].vc_conn;
			}
		[] NS_SP.receive(tr_NsUdReq(g_config.nsei, ?, ?, ?, *)) -> value rx_nsudr {
			/* load distribution function */
			var integer nsvc_idx := g_unblocked_nsvcs_data[rx_nsudr.lsp mod lengthof(g_unblocked_nsvcs_data)];
			NSVC.send(rx_nsudr) to g_nsvcs[nsvc_idx].vc_conn;
			}

		[] NS_SP.receive(tr_NsUdReq(?, ?, ?, ?, *)) -> value rx_nsudr {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("Received NsUnitdataReq for invalid NSEI: ", rx_nsudr));
			}
	}

	/* generate a list of v4 + v6 endpoints based on the NSVConfigurations. This is not strictly
	 * accurate, as we should create a list of _endpoints_, while we actually create a list of
	 * NSVCs.  Those are only identical as long as our peer only implements one endpoint */
	private function gen_sns_ip_elems(out template (omit) IP4_Elements v4_out,
					  out template (omit) IP6_Elements v6_out) runs on NS_CT {
		var integer i;
		var IP4_Elements v4 := {};
		var IP6_Elements v6 := {};

		for (i := 0; i < lengthof(g_config.nsvc); i := i + 1) {
			var NSVCConfiguration nsvc_cfg := g_config.nsvc[i];
			if (not ischosen(nsvc_cfg.provider.ip)) {
				continue;
			}
			if (nsvc_cfg.provider.ip.address_family == AF_INET) {
				v4 := v4 & { valueof(ts_SNS_IPv4(nsvc_cfg.provider.ip.local_ip,
								 nsvc_cfg.provider.ip.local_udp_port,
								 nsvc_cfg.provider.ip.signalling_weight,
								 nsvc_cfg.provider.ip.data_weight)) };
			} else if (nsvc_cfg.provider.ip.address_family == AF_INET6) {
				v6 := v6 & { valueof(ts_SNS_IPv6(nsvc_cfg.provider.ip.local_ip,
								 nsvc_cfg.provider.ip.local_udp_port,
								 nsvc_cfg.provider.ip.signalling_weight,
								 nsvc_cfg.provider.ip.data_weight)) };
			}
		}

		/* we must not return empty lists, but 'omit' as otherwise we get wrong SNS IEs */
		if (lengthof(v4) == 0) {
			v4_out := omit;
		} else {
			v4_out := v4;
		}
		if (lengthof(v6) == 0) {
			v6_out := omit;
		} else {
			v6_out := v6;
		}
	}

	/* simple IP Sub-Network Service responder for the SGSN side. This is not a full implementation
	 * of the protocol, merely sufficient to make the PCU/BSS side happy to proceed */
	private altstep as_vcg_sns_sgsn() runs on NS_CT {
		var SnsIndication sind;
		var NSVC_CT vc;
		[] NSVC.receive(SnsIndication:{?, tr_SNS_SIZE(g_config.nsei)}) -> value sind sender vc {
			/* blindly acknowledge whatever the PCU sends */
			NSVC.send(SnsRequest:{sind.nsvci, ts_SNS_SIZE_ACK(g_config.nsei, omit)}) to vc;
		}
		/* FIXME: We assume our peer has only one endpoint */
		[] NSVC.receive(SnsIndication:{?, tr_SNS_CONFIG(g_config.nsei, true,
				    {tr_SNS_IPv4(g_config.nsvc[0].provider.ip.remote_ip,
						 g_config.nsvc[0].provider.ip.remote_udp_port)})})
										-> value sind sender vc {
			/* blindly acknowledge whatever the PCU sends */
			NSVC.send(SnsRequest:{sind.nsvci, ts_SNS_CONFIG_ACK(g_config.nsei, omit)}) to vc;
			/* send a SNS-CONFIG in response and expect a SNS-CONFIG-ACK */
			var template (omit) IP4_Elements v4;
			var template (omit) IP6_Elements v6;
			gen_sns_ip_elems(v4, v6);
			NSVC.send(SnsRequest:{sind.nsvci,
					      ts_SNS_CONFIG(g_config.nsei, true, v4, v6)}) to vc;
			alt {
			[] NSVC.receive(SnsIndication:{sind.nsvci,
							tr_SNS_CONFIG_ACK(g_config.nsei, omit)}) from vc {
				/* success */
				log("SNS Config succeeded. Sending Alive");
				/* inform all NS-VC that they are now considered alive */
				for (var integer i := 0; i < lengthof(g_nsvcs); i := i+1) {
					NSVC.send(NsCtrlRequest:StartAliveProcedure) to g_nsvcs[i].vc_conn;
					}
				}
			[] NSVC.receive(SnsIndication:{sind.nsvci,
							tr_SNS_CONFIG_ACK(g_config.nsei, ?)}) from vc {
				setverdict(fail, "Unexpected SNS-CONFIG-NACK");
				self.stop;
				}
			}
		}
		[] NSVC.receive(SnsIndication:{?, tr_SNS_CONFIG(g_config.nsei, false, ?)}) { /* ignore */}
		[] NSVC.receive(SnsIndication:{?, tr_SNS_CONFIG(g_config.nsei, true, ?)}) {
			setverdict(fail, "Unexpected SNS-CONFIG content");
			self.stop;
		}
		[] NSVC.receive(SnsIndication:{?, tr_SNS_CONFIG(?, ?, ?)}) {
			setverdict(fail, "SNS-CONFIG from unexpected NSEI");
			self.stop;
		}
	}

	/***********************************************************************
	 per-NSVC component. Exists once for each NS-VC in the NS-VCG
	 ***********************************************************************/

	type component NSVC_CT {
		/* UDP port towards the bottom (IUT) */
		port NS_PROVIDER_PT NSCP;
		var NS_Provider_IPL4_CT vc_NSP_IP;
#ifdef NS_EMULATION_FR
		var NS_Provider_FR_CT vc_NSP_FR;
#endif

		/* port towards the NS_CT */
		port NSint_SP_PT NS_SP;

		/* configuration passed by the user */
		var NSVCConfiguration	g_nsvc_config;
		/* we cannot access the NS_CT.config and hence need to copy those */
		var NSConfiguration	g_config;

		var NsvcState		vc_state := NSVC_S_DEAD_BLOCKED;

		timer Tns_alive := 3.0;
		timer Tns_test := 10.0;
		timer Tns_block := 10.0;
		timer Tns_reset := 10.0;
	}

	function NSVCStart(NSVCConfiguration init_config, NSConfiguration init_g_config, charstring id := testcasename()) runs on NSVC_CT {
		g_nsvc_config := init_config;
		g_config := init_g_config;
		f_init(id & "-NSVCemu" & int2str(g_nsvc_config.nsvci));
		f_ScanEvents();
	}

	private function f_init(charstring id) runs on NSVC_CT {
		if (ischosen(g_nsvc_config.provider.ip)) {
			/* Connect the UDP socket */
			vc_NSP_IP := NS_Provider_IPL4_CT.create(id & "-provIP");
			connect(self:NSCP, vc_NSP_IP:NSE);
			vc_NSP_IP.start(NS_Provider_IPL4.main(g_nsvc_config, g_config, id));
#ifdef NS_EMULATION_FR
		} else if (ischosen(g_nsvc_config.provider.fr)) {
			vc_NSP_FR := NS_Provider_FR_CT.create(id & "-provFR");
			connect(self:NSCP, vc_NSP_FR:NSE);
			vc_NSP_FR.start(NS_Provider_FR.main(g_nsvc_config, g_config, id));
#endif
		} else {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unsupported NS provider");
		}

		f_change_state(NSVC_S_DEAD_BLOCKED);
	}

	private function f_change_state(NsvcState new_state) runs on NSVC_CT {
		var NsvcState old_state := vc_state;
		vc_state := new_state;
		log("NSVC ", g_nsvc_config.nsvci, " State Transition: ", old_state, " -> ", new_state);
		NS_SP.send(ts_NsStsInd(g_config.nsei, g_nsvc_config.nsvci, old_state, new_state));
	}

	private function f_sendReset() runs on NSVC_CT {
		NSCP.send(ts_NS_RESET(NS_CAUSE_OM_INTERVENTION, g_nsvc_config.nsvci, g_config.nsei));
		Tns_reset.start;
		vc_state := NSVC_S_WAIT_RESET;
	}

	private function f_sendAlive() runs on NSVC_CT {
		NSCP.send(t_NS_ALIVE);
		Tns_alive.start;
	}

	private function f_sendUnblock() runs on NSVC_CT {
		NSCP.send(t_NS_UNBLOCK);
		Tns_block.start;
	}

	private function f_sendBlock(NsCause cause) runs on NSVC_CT {
		NSCP.send(ts_NS_BLOCK(cause, g_nsvc_config.nsvci));
		Tns_block.start;
	}

	private altstep as_allstate() runs on NSVC_CT {
		var PDU_NS rf;
		var ASP_Event evt;

		/* transition to DEAD if t_alive times out */
		[] Tns_alive.timeout {
			log("Tns-alive expired: changing to DEAD_BLOCKED + starting Tns-test");
			f_change_state(NSVC_S_DEAD_BLOCKED);
			Tns_test.start;
		}

		[] Tns_test.timeout {
			log("Tns-test expired: sending NS-ALIVE");
			f_sendAlive();
		}

		/* Stop t_alive when receiving ALIVE-ACK */
		[Tns_alive.running] NSCP.receive(t_NS_ALIVE_ACK) {
			log("Rx NS-ALIVE-ACK: stopping Tns-alive; starting Tns-test");
			Tns_alive.stop;
			Tns_test.start;
		}

		/* respond to NS-ALIVE with NS-ALIVE-ACK */
		[] NSCP.receive(t_NS_ALIVE) {
			NSCP.send(t_NS_ALIVE_ACK);
		}

		/* Respond to BLOCK for wrong NSVCI */
		[] NSCP.receive(tr_NS_BLOCK(?, ?)) -> value rf {
			log("Rx NS-BLOCK for unknown NSVCI");
			/* FIXME */
		}

		[not g_config.handle_sns] as_handle_reset();

		[g_config.handle_sns and ischosen(g_nsvc_config.provider.ip)] as_nsvc_sns();

		/* default case of handling unknown PDUs */
		[] NSCP.receive(PDU_NS: ?) -> value rf {
			log("Rx Unexpected NS PDU ", rf," in state ", vc_state);
			NSCP.send(ts_NS_STATUS(NS_CAUSE_PDU_NOT_COMPATIBLE_WITH_PROTOCOL_STATE, rf));
		}
	}

	private altstep as_handle_reset() runs on NSVC_CT {
		var PDU_NS rf;

		[g_config.role_sgsn] NSCP.receive(NS_Provider_Evt:{link_status:=NS_PROV_LINK_STATUS_UP}) {
			log("Provider Link came up: waiting for NS-RESET");
			}

		[not g_config.role_sgsn] NSCP.receive(NS_Provider_Evt:{link_status:=NS_PROV_LINK_STATUS_UP}) {
			log("Provider Link came up: sending NS-RESET");
			f_sendReset();
			}

		/* Respond to RESET with correct NSEI/NSVCI */
		[] NSCP.receive(tr_NS_RESET(?, g_nsvc_config.nsvci, g_config.nsei)) -> value rf {
			f_change_state(NSVC_S_ALIVE_BLOCKED);
			NSCP.send(ts_NS_RESET_ACK(g_nsvc_config.nsvci, g_config.nsei));
			log("Rx NS-RESET: Sending NS-ALIVE");
			f_sendAlive();
			Tns_test.start;
		}

		/* Respond to RESET with wrong NSEI/NSVCI */
		[] NSCP.receive(tr_NS_RESET(?, ?, ?)) -> value rf {
			log("Rx NS-RESET for unknown NSEI/NSVCI");
			/* FIXME */
		}
	}

	private altstep as_nsvc_sns() runs on NSVC_CT {
		var PDU_NS rf;
		var SnsRequest sreq;
		[] NSCP.receive(NS_Provider_Evt:{link_status:=NS_PROV_LINK_STATUS_UP}) {
			log("Provider Link came up. Waiting for SNS Size");
		}

		/* pass up to NS-VCG */
		[] NSCP.receive(tr_SNS(g_config.nsei)) -> value rf {
			NS_SP.send(SnsIndication:{g_nsvc_config.nsvci, rf});
		}
		[] NSCP.receive(tr_SNS(?)) -> value rf {
			setverdict(fail, "SNS from unexpected NSEI: ", rf);
			self.stop;
		}
		[] NS_SP.receive(SnsRequest:{g_nsvc_config.nsvci, ?}) -> value sreq {
			NSCP.send(sreq.ns);
		}
		[] NS_SP.receive(SnsRequest:?) -> value sreq {
			setverdict(fail, "Unexpected SNS from NSVC: ", sreq);
			self.stop;
		}
		[] NS_SP.receive(NsCtrlRequest:StartAliveProcedure) {
			f_change_state(NSVC_S_ALIVE_UNBLOCKED);
			f_sendAlive();
			Tns_test.start;
		}
	}

	private altstep as_alive_blocked() runs on NSVC_CT {
		var PDU_NS rf;
		/* bogus block, just respond with ACK */
		[] NSCP.receive(tr_NS_BLOCK(?, g_nsvc_config.nsvci)) -> value rf {
			NSCP.send(ts_NS_BLOCK_ACK(g_nsvc_config.nsvci));
		}
		/* Respond to UNBLOCK with UNBLOCK-ACK + change state */
		[] NSCP.receive(t_NS_UNBLOCK) -> value rf {
			NSCP.send(t_NS_UNBLOCK_ACK);
			Tns_block.stop;
			f_change_state(NSVC_S_ALIVE_UNBLOCKED);
		}
		[] NSCP.receive(t_NS_UNBLOCK_ACK) -> value rf {
			Tns_block.stop;
			f_change_state(NSVC_S_ALIVE_UNBLOCKED);
		}
		/* tolerate a late NS-BLOCK-ACK from peer */
		[] NSCP.receive(tr_NS_BLOCK_ACK(g_nsvc_config.nsvci)) -> value rf {
		}
		[] Tns_block.timeout {
			/* repeat unblock transmission */
			f_sendUnblock();
		}
	}

	private altstep as_alive_unblocked() runs on NSVC_CT {
		var NsUnitdataRequest ud_req;
		var PDU_NS rf;
		/* bogus unblock, just respond with ACK */
		[] NSCP.receive(t_NS_UNBLOCK) -> value rf {
			NSCP.send(t_NS_UNBLOCK_ACK);
		}
		/* Respond to BLOCK with BLOCK-ACK + change state */
		[] NSCP.receive(tr_NS_BLOCK(?, g_nsvc_config.nsvci)) -> value rf {
			NSCP.send(ts_NS_BLOCK_ACK(g_nsvc_config.nsvci));
			Tns_block.stop;
			f_change_state(NSVC_S_ALIVE_BLOCKED);
		}
		[] NSCP.receive(tr_NS_BLOCK_ACK(g_nsvc_config.nsvci)) -> value rf {
			Tns_block.stop;
		}
		/* tolerate a late NS-UNBLOCK-ACK from peer */
		[] NSCP.receive(t_NS_UNBLOCK_ACK) -> value rf {
		}

		[not ischosen(g_nsvc_config.provider.ip) or
		 g_nsvc_config.provider.ip.data_weight > 0] as_alive_unblocked_data();

		[not ischosen(g_nsvc_config.provider.ip) or
		 g_nsvc_config.provider.ip.signalling_weight > 0] as_alive_unblocked_sig();

		/* catch any violations of above rule */
		[ischosen(g_nsvc_config.provider.ip)] NSCP.receive(tr_NS_UNITDATA(?, ?, ?)) -> value rf {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("Unexpected Rx NS-UNITDATA on NSVC with data_weight=",
						g_nsvc_config.provider.ip.data_weight, ", sig_weight=",
						g_nsvc_config.provider.ip.signalling_weight, ": ", rf));
		}
		[ischosen(g_nsvc_config.provider.ip)] NS_SP.receive(tr_NsUdReq(g_config.nsei, ?, ?, *, *)) -> value ud_req {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("Unexpected Rx TX-UNITDATA on NSVC with data_weight=",
						g_nsvc_config.provider.ip.data_weight, ", sig_weight=",
						g_nsvc_config.provider.ip.signalling_weight, ": ", ud_req));
		}
	}

	/* user data transfer; only permitted for some NS-VC */
	private altstep as_alive_unblocked_data() runs on NSVC_CT {
		var NsUnitdataRequest ud_req;
		var PDU_NS rf;
		/* NS-UNITDATA PDU from network to NS-UNITDATA.ind to user */
		[] NSCP.receive(tr_NS_UNITDATA_User(?, ?)) -> value rf {
			NS_SP.send(ts_NsUdInd(g_config.nsei, g_nsvc_config.nsvci,
					     oct2int(rf.pDU_NS_Unitdata.bVCI),
					     rf.pDU_NS_Unitdata.nS_SDU));
		}
		/* NS-UNITDATA.req from user to NS-UNITDATA PDU on network */
		[] NS_SP.receive(tr_NsUdReq(g_config.nsei, t_BssgpBvciUser, ?, ?, omit)) -> value ud_req {
			/* using raw octetstring PDU */
			NSCP.send(ts_NS_UNITDATA(t_SduCtrlB, ud_req.bvci, ud_req.sdu));
		}
		[] NS_SP.receive(tr_NsUdReq(g_config.nsei, t_BssgpBvciUser, ?, omit, ?)) -> value ud_req {
			/* using decoded BSSGP PDU that we need to encode first */
			var octetstring enc := enc_PDU_BSSGP(ud_req.bssgp);
			NSCP.send(ts_NS_UNITDATA(t_SduCtrlB, ud_req.bvci, enc));
		}
	}

	/* signalling (BVCI=0) transfer; only permitted for some NS-VC */
	private altstep as_alive_unblocked_sig() runs on NSVC_CT {
		var NsUnitdataRequest ud_req;
		var PDU_NS rf;
		/* NS-UNITDATA PDU from network to NS-UNITDATA.ind to user */
		[] NSCP.receive(tr_NS_UNITDATA(?, 0, ?)) -> value rf {
			NS_SP.send(ts_NsUdInd(g_config.nsei, g_nsvc_config.nsvci,
					     oct2int(rf.pDU_NS_Unitdata.bVCI),
					     rf.pDU_NS_Unitdata.nS_SDU));
		}
		/* NS-UNITDATA.req from user to NS-UNITDATA PDU on network */
		[] NS_SP.receive(tr_NsUdReq(g_config.nsei, 0, ?, ?, omit)) -> value ud_req {
			/* using raw octetstring PDU */
			NSCP.send(ts_NS_UNITDATA(t_SduCtrlB, ud_req.bvci, ud_req.sdu));
		}
		[] NS_SP.receive(tr_NsUdReq(g_config.nsei, 0, ?, omit, ?)) -> value ud_req {
			/* using decoded BSSGP PDU that we need to encode first */
			var octetstring enc := enc_PDU_BSSGP(ud_req.bssgp);
			NSCP.send(ts_NS_UNITDATA(t_SduCtrlB, ud_req.bvci, enc));
		}
	}

	private altstep as_wait_reset() runs on NSVC_CT {
		var PDU_NS rf;
		[] Tns_reset.timeout {
			/* If the sending entity of an NS-RESET PDU receives no NS-RESET-ACK PDU before timer
			 * Tns-reset expires the corresponding NS-VCs shall remain blocked and dead and the
			 * entire reset procedure shall be repeated */
			f_sendReset();
			}
		[] NSCP.receive(tr_NS_RESET_ACK(g_nsvc_config.nsvci, g_config.nsei)) -> value rf {
			Tns_reset.stop;
			f_change_state(NSVC_S_ALIVE_BLOCKED);
			f_sendAlive();
			f_sendUnblock();
		}
	}

	private function f_ScanEvents() runs on NSVC_CT {
		var PDU_NS rf;
		while (true) {
			alt {
			[vc_state == NSVC_S_WAIT_RESET] as_wait_reset();
			[vc_state == NSVC_S_ALIVE_BLOCKED] as_alive_blocked();
			[vc_state == NSVC_S_ALIVE_UNBLOCKED] as_alive_unblocked();
			[] as_allstate();
			}
		}
	}
}
