Expand BSSGP helpers + codec to cover expansion + compaction
diff --git a/gprs_gb/NS_Types.ttcn b/gprs_gb/NS_Types.ttcn
new file mode 100644
index 0000000..ee2444d
--- /dev/null
+++ b/gprs_gb/NS_Types.ttcn
@@ -0,0 +1,103 @@
+module NS_Types {
+ import from General_Types all;
+ import from Osmocom_Types all;
+ import from GSM_Types all;
+ import from BSSGP_Types 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)" };
+
+ 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 NsPdu {
+ NsPduType pdu_type,
+ NsTLVs tlvs optional
+ } with { variant "" };
+
+ 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)" };
+
+} with { encode "RAW" };