/* GPRS-NS Emulation in TTCN-3
 * (C) 2018-2020 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
	};
	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 NS_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 := {};
	};
	type record NsvcTableEntry {
		Nsvci nsvci,
		NSVC_CT vc_conn,
		NsvcState state
	};
	type record of NsvcTableEntry NsvcTable;
	type record of integer ro_integer;

	/* 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.nsvci := nsvc_cfg.nsvci;
		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].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 */
			g_unblocked_nsvcs := g_unblocked_nsvcs & {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 := {};
			for (var integer j := 0; j < lengthof(g_unblocked_nsvcs); j := j+1) {
				if (g_unblocked_nsvcs[j] != i) {
					new_unblocked_nsvcs := new_unblocked_nsvcs & {j};
				}
			}
			g_unblocked_nsvcs := new_unblocked_nsvcs;
		}
		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);
			}
		[] 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, ?, ?, ?, *)) -> value rx_nsudr {
			/* load distribution function */
			var integer nsvc_idx := g_unblocked_nsvcs[rx_nsudr.lsp mod lengthof(g_unblocked_nsvcs)];
			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));
			}
	}

	/***********************************************************************
	 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 NS_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 {
		var Result res;

		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.role_sgsn and g_config.handle_sns and ischosen(g_nsvc_config.provider.ip)] as_sns_sgsn();

		/* 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 */
		}
	}

	/* 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_sns_sgsn() 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: sending NS-ALIVE");
			f_sendAlive();
			}

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

		[] NSCP.receive(tr_SNS_SIZE(g_config.nsei)) -> value rf {
			/* blindly acknowledge whatever the PCU sends */
			NSCP.send(ts_SNS_SIZE_ACK(g_config.nsei, omit));
		}
		[] NSCP.receive(tr_SNS_SIZE(?)) {
			setverdict(fail, "SNS-SIZE from unexpected NSEI");
			self.stop;
		}
		[] NSCP.receive(tr_SNS_CONFIG(g_config.nsei, true,
				    {tr_SNS_IPv4(g_nsvc_config.provider.ip.remote_ip,
						 g_nsvc_config.provider.ip.remote_udp_port)})) -> value rf {
			/* blindly acknowledge whatever the PCU sends */
			NSCP.send(ts_SNS_CONFIG_ACK(g_config.nsei, omit));
			/* send a SNS-CONFIG in response and expect a SNS-CONFIG-ACK */
			var IP4_Elements v4 := { valueof(ts_SNS_IPv4(g_nsvc_config.provider.ip.local_ip,
								     g_nsvc_config.provider.ip.local_udp_port)) };
			NSCP.send(ts_SNS_CONFIG(g_config.nsei, true, v4));
			alt {
			[] NSCP.receive(tr_SNS_CONFIG_ACK(g_config.nsei, omit)) {
				/* success */
				}
			[] NSCP.receive(tr_SNS_CONFIG_ACK(g_config.nsei, ?)) {
				setverdict(fail, "Unexpected SNS-CONFIG-NACK");
				self.stop;
				}
			}
		}
		[] NSCP.receive(tr_SNS_CONFIG(g_config.nsei, false, ?)) { /* ignore */}
		[] NSCP.receive(tr_SNS_CONFIG(g_config.nsei, true, ?)) {
			setverdict(fail, "Unexpected SNS-CONFIG content");
			self.stop;
		}
		[] NSCP.receive(tr_SNS_CONFIG(?, ?, ?)) {
			setverdict(fail, "SNS-CONFIG from unexpected NSEI");
			self.stop;
		}
	}

	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);
		}
		[] 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;
		}
		/* NS-UNITDATA PDU from network to NS-UNITDATA.ind to user */
		[] NSCP.receive(tr_NS_UNITDATA(?, ?, ?)) -> 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, ?, ?, ?, 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, ?, ?, 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();
			}
		}
	}
}
