/* 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) runs on NS_CT {
		config := init_config;
		f_init();
		f_ScanEvents();
	}

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

		if (ischosen(config.provider.ip)) {
			/* Connect the UDP socket */
			vc_NSP_IP := NS_Provider_IPL4_CT.create;
			connect(self:NSCP, vc_NSP_IP:NSE);
			vc_NSP_IP.start(NS_Provider_IPL4.main(config));
#ifdef NS_EMULATION_FR
		} else if (ischosen(config.provider.fr)) {
			vc_NSP_FR := NS_Provider_FR_CT.create;
			connect(self:NSCP, vc_NSP_FR:NSE);
			vc_NSP_FR.start(NS_Provider_FR.main(config));
#endif
		}

		f_change_state(NSE_S_DEAD_BLOCKED);
		/* Send the first NS-ALIVE to test the connection */
		if (not config.role_sgsn) {
			f_sendReset();
		}
	}

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

	/* port between NS_Provider and NS_CT */
	type port NS_PROVIDER_PT message {
		inout PDU_NS;
	} 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;
	}

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

	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("NS-ALIVE-ACK received: 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 */
		}

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

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

		[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));
		}
	}

	/* 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 */
	altstep as_sns_sgsn() runs on NS_CT {
		var PDU_NS rf;
		[] 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 function f_ScanEvents() runs on NS_CT {
		var NsUnitdataRequest ud_req;
		var PDU_NS rf;
		var default d;

		d := activate(as_allstate());

		while (true) {
		if (g_state == NSE_S_DEAD_BLOCKED) {
			alt {
				[false] any timer.timeout {}
			}
		} else if (g_state == NSE_S_WAIT_RESET) {
			alt {
				[] NSCP.receive(tr_NS_RESET_ACK(config.nsvci, config.nsei)) -> value rf {
					f_change_state(NSE_S_ALIVE_BLOCKED);
					f_sendAlive();
					f_sendUnblock();
				}
			}
		} else if (g_state == NSE_S_ALIVE_BLOCKED) {
			alt {
				/* 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();
				}
			}
		} else if (g_state == NSE_S_ALIVE_UNBLOCKED) {
			alt {
				/* 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));
				}
			}
		}

		} /* while */
		//deactivate(d);
	}
}
