/* 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 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,
		octetstring	sdu optional,
		PDU_BSSGP	bssgp optional
	}

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

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

	template NsUnitdataIndication t_NsUdInd(Nsei nsei, BssgpBvci bvci, octetstring sdu) := {
		bvci := bvci,
		nsei := nsei,
		sdu := sdu,
		bssgp := dec_PDU_BSSGP(sdu)
	}

	type record NsStatusIndication {
		Nsei		nsei,
		Nsvci		nsvci,
		NseState	old_state,
		NseState	new_state
	}

	template NsStatusIndication t_NsStsInd(Nsei nsei, Nsvci nsvci, NseState old_state, NseState state) := {
		nsei := nsei,
		nsvci := nsvci,
		old_state := old_state,
		new_state := state
	}

	type enumerated NseState {
		NSE_S_DEAD_BLOCKED,
		NSE_S_WAIT_RESET,
		NSE_S_ALIVE_BLOCKED,
		NSE_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" };

	function NSStart(NSConfiguration init_config, charstring id := testcasename()) runs on NS_CT {
		config := init_config;
		f_init(id & "-NSemu");
		f_ScanEvents();
	}

	private function f_init(charstring id) runs on NS_CT {
		var Result res;

		if (ischosen(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(config, id));
#ifdef NS_EMULATION_FR
		} else if (ischosen(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(config, id));
#endif
		}

		f_change_state(NSE_S_DEAD_BLOCKED);
	}

	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 component NS_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

		/* NS-User SAP towards the user */
		port NS_SP_PT NS_SP;

		var NSConfiguration config;

		var NseState		g_state := NSE_S_DEAD_BLOCKED;

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

	type record NSConfigurationIP {
		AddressFamily address_family,
		PortNumber local_udp_port,
		charstring local_ip,
		PortNumber remote_udp_port,
		charstring remote_ip
	};
	type record NSConfigurationFR {
		charstring netdev,	/* HDLC net-device for AF_PACKET socket */
		integer dlci
	};
	type union NSConfigurationP {
		NSConfigurationIP ip,
		NSConfigurationFR fr
	};
	type record NSConfiguration {
		NSConfigurationP provider,
		Nsvci nsvci,
		Nsvci nsei,
		boolean role_sgsn,
		boolean handle_sns
	}

	private function f_change_state(NseState new_state) runs on NS_CT {
		var NseState old_state := g_state;
		g_state := new_state;
		log("NS State Transition: ", old_state, " -> ", new_state);
		NS_SP.send(t_NsStsInd(config.nsei, config.nsvci, old_state, new_state));
	}

	private function f_sendReset() runs on NS_CT {
		NSCP.send(ts_NS_RESET(NS_CAUSE_OM_INTERVENTION, config.nsvci, config.nsei));
		Tns_reset.start;
		g_state := NSE_S_WAIT_RESET;
	}

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

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

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

	private altstep as_allstate() runs on NS_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(NSE_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 config.handle_sns] as_handle_reset();

		[config.role_sgsn and config.handle_sns and ischosen(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 ", g_state);
			NSCP.send(ts_NS_STATUS(NS_CAUSE_PDU_NOT_COMPATIBLE_WITH_PROTOCOL_STATE, rf));
		}
	}

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

		[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 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(?, config.nsvci, config.nsei)) -> value rf {
			f_change_state(NSE_S_ALIVE_BLOCKED);
			NSCP.send(ts_NS_RESET_ACK(config.nsvci, 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 NS_CT {
		var PDU_NS rf;
		[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 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(config.nsei)) -> value rf {
			/* blindly acknowledge whatever the PCU sends */
			NSCP.send(ts_SNS_SIZE_ACK(config.nsei, omit));
		}
		[] NSCP.receive(tr_SNS_SIZE(?)) {
			setverdict(fail, "SNS-SIZE from unexpected NSEI");
			self.stop;
		}
		[] NSCP.receive(tr_SNS_CONFIG(config.nsei, true,
				    {tr_SNS_IPv4(config.provider.ip.remote_ip,
						 config.provider.ip.remote_udp_port)})) -> value rf {
			/* blindly acknowledge whatever the PCU sends */
			NSCP.send(ts_SNS_CONFIG_ACK(config.nsei, omit));
			/* send a SNS-CONFIG in response and expect a SNS-CONFIG-ACK */
			var IP4_Elements v4 := { valueof(ts_SNS_IPv4(config.provider.ip.local_ip, config.provider.ip.local_udp_port)) };
			NSCP.send(ts_SNS_CONFIG(config.nsei, true, v4));
			alt {
			[] NSCP.receive(tr_SNS_CONFIG_ACK(config.nsei, omit)) {
				/* success */
				}
			[] NSCP.receive(tr_SNS_CONFIG_ACK(config.nsei, ?)) {
				setverdict(fail, "Unexpected SNS-CONFIG-NACK");
				self.stop;
				}
			}
		}
		[] NSCP.receive(tr_SNS_CONFIG(config.nsei, false, ?)) { /* ignore */}
		[] NSCP.receive(tr_SNS_CONFIG(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 NS_CT {
		var PDU_NS rf;
		/* bogus block, just respond with ACK */
		[] NSCP.receive(tr_NS_BLOCK(?, config.nsvci)) -> value rf {
			NSCP.send(ts_NS_BLOCK_ACK(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(NSE_S_ALIVE_UNBLOCKED);
		}
		[] NSCP.receive(t_NS_UNBLOCK_ACK) -> value rf {
			Tns_block.stop;
			f_change_state(NSE_S_ALIVE_UNBLOCKED);
		}
		[] Tns_block.timeout {
			/* repeat unblock transmission */
			f_sendUnblock();
		}
	}

	private altstep as_alive_unblocked() runs on NS_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(?, config.nsvci)) -> value rf {
			NSCP.send(ts_NS_BLOCK_ACK(config.nsvci));
			Tns_block.stop;
			f_change_state(NSE_S_ALIVE_BLOCKED);
		}
		[] NSCP.receive(tr_NS_BLOCK_ACK(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(t_NsUdInd(config.nsei,
					     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(t_NsUdReq(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(t_NsUdReq(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 NS_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(config.nsvci, config.nsei)) -> value rf {
			Tns_reset.stop;
			f_change_state(NSE_S_ALIVE_BLOCKED);
			f_sendAlive();
			f_sendUnblock();
		}
	}

	private function f_ScanEvents() runs on NS_CT {
		var PDU_NS rf;
		while (true) {
			alt {
			[g_state == NSE_S_WAIT_RESET] as_wait_reset();
			[g_state == NSE_S_ALIVE_BLOCKED] as_alive_blocked();
			[g_state == NSE_S_ALIVE_UNBLOCKED] as_alive_unblocked();
			[] as_allstate();
			}
		}
	}
}
