module NS_Types {
	import from General_Types all;
	import from Osmocom_Types all;
	import from GSM_Types all;
	import from BSSGP_Types all;
	import from BSSGP_Helper_Functions all;

	/* TS 48.016 10.3.7 */
	type enumerated NsPduType {
		NS_PDUT_NS_UNITDATA	('00000000'B),
		NS_PDUT_NS_RESET	('00000010'B),
		NS_PDUT_NS_RESET_ACK	('00000011'B),
		NS_PDUT_NS_BLOCK	('00000100'B),
		NS_PDUT_NS_BLOCK_ACK	('00000101'B),
		NS_PDUT_NS_UNBLOCK	('00000110'B),
		NS_PDUT_NS_UNBLOCK_ACK	('00000111'B),
		NS_PDUT_NS_STATUS	('00001000'B),
		NS_PDUT_NS_ALIVE	('00001010'B),
		NS_PDUT_NS_ALIVE_ACK	('00001011'B)
		/* FIXME: SNS */
	} with { variant "FIELDLENGTH(8)" };

	/* TS 48.016 10.3 */
	type enumerated NsIEI {
		NS_IEI_CAUSE		('00000000'B),
		NS_IEI_NSVCI		('00000001'B),
		NS_IEI_NS_PDU		('00000010'B),
		NS_IEI_BVCI		('00000011'B),
		NS_IEI_NSEI		('00000100'B),
		NS_IEI_LIST_IPv4	('00000101'B),
		NS_IEI_LIST_IPv6	('00000110'B),
		NS_IEI_MAX_NUM_NSVC	('00000111'B),
		NS_IEI_NUM_IPv4_EP	('00001000'B),
		NS_IEI_NUM_IPv6_EP	('00001001'B),
		NS_IEI_RESET_FLAG	('00001010'B),
		NS_IEI_IP_ADDRESS	('00001011'B)
	} with { variant "FIELDLENGTH(8)" };

	/* TS 48.016 10.3.2 */
	type enumerated NsCause {
		NS_CAUSE_TRANSIT_NETWORK_FAILURE		('00000000'B),
		NS_CAUSE_OM_INTERVENTION			('00000001'B),
		NS_CAUSE_EQUIPMENT_FAILURE			('00000010'B),
		NS_CAUSE_NSVC_BLOCKED				('00000011'B),
		NS_CAUSE_NSVC_UNKNOWN				('00000100'B),
		NS_CAUSE_BVCI_UNKNOWN_AT_NSE			('00000101'B),
		NS_CAUSE_SEMANTICALLY_INCORRECT_PDU		('00001000'B),
		NS_CAUSE_PDU_NOT_COMPATIBLE_WITH_PROTOCOL_STATE	('00001010'B),
		NS_CAUSE_PROTOCOL_ERROR_UNSPEIFIED		('00001011'B),
		NS_CAUSE_INVALID_ESSENTIAL_IE			('00001100'B),
		NS_CAUSE_MISSING_ESSENTIAL_IE			('00001101'B),
		NS_CAUSE_INVALID_NR_OF_IPv4_ENDPOINTS		('00001110'B),
		NS_CAUSE_INVALID_NR_OF_IPv6_ENDPOINTS		('00001111'B),
		NS_CAUSE_INVALID_NR_OF_NSVCS			('00010000'B),
		NS_CAUSE_INVALID_WEIGHTS			('00010001'B),
		NS_CAUSE_UNKNOWN_IP_ENDPOINT			('00010010'B),
		NS_CAUSE_UNKNOWN_IP_ADDRESS			('00010011'B),
		NS_CAUSE_IP_TEST_FAILEDA			('00010100'B)
	} with { variant "FIELDLENGTH(8)" };

	/* TS 48.016 10.3.9 */
	type record NsSduControlBits {
		BIT6	spare,
		boolean c,
		boolean r
	} with { variant (c) "FIELDLENGTH(1)"
		 variant (r) "FIELDLENGTH(1)"
	};

	template NsSduControlBits t_SduCtrlB := {
		spare := '000000'B,
		c := false,
		r := false
	}

	type uint16_t Nsvci;
	type uint16_t Nsei;

	type union NsIeUnion {
		BssgpBvci		bvci,		/* 10.3.1 */
		NsCause			cause,		/* 10.3.2 */
		uint16_t		max_num_nsvc,	/* 10.3.2e */
		uint16_t		num_ipv4_ep,	/* 10.3.2f */
		uint16_t		num_ipv6_ep,	/* 10.3.2g */
		Nsvci			nsvci,		/* 10.3.5 */
		Nsei			nsei,		/* 10.3.6 */
		octetstring 		other
	};

	type record NsTLV {
		NsIEI		iei,
		uint16_t	len,
		NsIeUnion	u
	} with {
		variant (u) "CROSSTAG(
				bvci, 			iei = NS_IEI_BVCI;
				cause,			iei = NS_IEI_CAUSE;
				max_num_nsvc,		iei = NS_IEI_MAX_NUM_NSVC;
				num_ipv4_ep,		iei = NS_IEI_NUM_IPv4_EP;
				num_ipv6_ep,		iei = NS_IEI_NUM_IPv6_EP;
				nsvci,			iei = NS_IEI_NSVCI;
				nsei,			iei = NS_IEI_NSEI;
				other,			OTHERWISE)"
		variant (len) "LENGTHTO(u)"
	};

	type record of NsTLV NsTLVs;

	type record NsPduUnitdata {
		NsSduControlBits	control_bits,
		BssgpBvci		bvci,
		octetstring		sdu
	} with { variant "" };

	type record NsPduOther {
		NsTLVs		tlvs optional
	} with { variant "" };

	type union NsPduUnion {
		NsPduUnitdata	unitdata,
		NsPduOther	other
	} with { variant "" };

	type record NsPdu {
		NsPduType	pdu_type,
		NsPduUnion	u
	} with { variant (u) "CROSSTAG(
				unitdata,		pdu_type = NS_PDUT_NS_UNITDATA;
				other,			OTHERWISE)"
	};

	external function enc_NsPdu(in NsPdu pdu) return octetstring
		with { extension "prototype(convert) encode(RAW)" };
	external function dec_NsPdu(in octetstring stream) return NsPdu
		with { extension "prototype(convert) decode(RAW)" };



	template NsTLV t_NS_IE_CAUSE(template NsCause cause) := {
		iei := NS_IEI_CAUSE,
		len := 1,
		u := { cause := cause }
	};

	template NsTLV t_NS_IE_NSVCI(template Nsvci nsvci) := {
		iei := NS_IEI_NSVCI,
		len := 2,
		u := { nsvci :=  nsvci }
	}

	template NsTLV t_NS_IE_NSEI(template Nsvci nsei) := {
		iei := NS_IEI_NSEI,
		len := 2,
		u := { nsei := nsei }
	}

	template NsTLV t_NsIE(NsIEI iei, NsIeUnion u) := {
		iei := iei,
		u := u
	}

	template NsTLV t_NsIE_other(NsIEI iei, octetstring val) := {
		iei := iei,
		len := lengthof(val),
		u := { other := val }
	}

	template NsPdu t_NS_RESET(template NsCause cause, template Nsvci nsvci, template Nsei nsei) := {
		pdu_type := NS_PDUT_NS_RESET,
		u := {
			other := {
				tlvs := { t_NS_IE_CAUSE(cause), t_NS_IE_NSVCI(nsvci), t_NS_IE_NSEI(nsei) }
			}
		}
	};

	template NsPdu t_NS_RESET_ACK(template Nsvci nsvci, template Nsei nsei) := {
		pdu_type := NS_PDUT_NS_RESET_ACK,
		u := {
			other := {
				tlvs := { t_NS_IE_NSVCI(nsvci), t_NS_IE_NSEI(nsei) }
			}
		}
	};

	template NsPdu t_NS_BLOCK(template NsCause cause, template Nsvci nsvci) := {
		pdu_type := NS_PDUT_NS_BLOCK,
		u := {
			other := {
				tlvs := { t_NS_IE_CAUSE(cause), t_NS_IE_NSVCI(nsvci) }
			}
		}
	}

	template NsPdu t_NS_BLOCK_ACK(template Nsvci nsvci) := {
		pdu_type := NS_PDUT_NS_BLOCK_ACK,
		u := {
			other := {
				tlvs := { t_NS_IE_NSVCI(nsvci) }
			}
		}
	}

	template NsPdu t_NsPduSimple(template NsPduType pdut) := { pdu_type := pdut, u := { other := { tlvs := omit } } };
	template NsPdu t_NS_ALIVE := t_NsPduSimple(NS_PDUT_NS_ALIVE);
	template NsPdu t_NS_ALIVE_ACK := t_NsPduSimple(NS_PDUT_NS_ALIVE_ACK);
	template NsPdu t_NS_UNBLOCK := t_NsPduSimple(NS_PDUT_NS_UNBLOCK);
	template NsPdu t_NS_UNBLOCK_ACK := t_NsPduSimple(NS_PDUT_NS_UNBLOCK_ACK);

	template NsPdu t_NS_STATUS(NsCause cause, NsPdu pdu) := {
		pdu_type := NS_PDUT_NS_STATUS,
		u := {
			other := {
				tlvs := { t_NS_IE_CAUSE(cause), t_NsIE_other(NS_IEI_NS_PDU, f_NS_compact_len(enc_NsPdu(pdu))) }
			}
		}
	}

	template NsPdu t_NS_UNITDATA(template NsSduControlBits bits, template BssgpBvci bvci, template octetstring sdu) := {
		pdu_type := NS_PDUT_NS_UNITDATA,
		u := {
			unitdata := {
				control_bits := bits,
				bvci := bvci,
				sdu := sdu
			}
		}
	}

} with { encode "RAW" };
