/* 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 {
		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;
		[] NSCP.receive(NS_Provider_Evt:{link_status:=NS_PROV_LINK_STATUS_UP}) {
			log("Provider Link came up. Waiting for SNS Size");
			}

		[] 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 */
				log("SNS Config succeeded. Sending Alive");
				f_change_state(NSVC_S_ALIVE_UNBLOCKED);
				f_sendAlive();
				Tns_test.start;
				}
			[] 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);
		}
		/* 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 {
		}
		/* 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();
			}
		}
	}
}
