module IuUP_Types { /* Definition of abstract types for the IuUP protocol as specified in * 3GPP TS 25.415. Uses the TITAN "RAW" codec to auto-generate encoder/decoder * functions. * * (C) 2017 by Harald Welte * All rights reserved. * * Released under the terms of GNU General Public License, Version 2 or * (at your option) any later version. */ import from Osmocom_Types all; import from General_Types all; /* See TS 25.415 6.6.3.1 */ type uint4_t IuUP_PDU_Type; /* See TS 25.415 6.6.3.2 */ type enumerated IuUP_AckNack { IuUP_ACKNACK_CTRL (0), IuUP_ACKNACK_ACK (1), IuUP_ACKNACK_NACK (2), IuUP_ACKNACK_RESERVED (3) } with { variant "FIELDLENGTH(2)" }; /* See TS 25.415 6.6.3.3 */ type uint4_t IuUP_FrameNr; /* See TS 25.415 6.6.3.5 */ type enumerated IuUP_FQC { IuUP_FQC_GOOD (0), IuUP_FQC_BAD (1), IuUP_FQC_BAD_RADIO (2), IuUP_FQC_SPARE (3) } with { variant "FIELDLENGTH(2)" }; /* See TS 25.415 6.6.3.6 */ type uint6_t IuUP_RFCI; /* See TS 25.415 6.6.3.7 */ type enumerated IuUP_ProcedureIndicator { IuUP_PRI_INITIALIZATION (0), IuUP_PRI_RATE_CONTROL (1), IuUP_PRI_TIME_ALIGNMENT (2), IuUP_PRI_ERROR_EVENT (3) /* reserved */ } with { variant "FIELDLENGTH(4)" }; /* See TS 25.415 6.6.3.13 */ type uint6_t IuUP_NumOfRfciInd; /* See TS 25.415 6.6.3.15 */ type enumerated IuUP_ErrorDistance { IuUP_ERR_DIST_LOCAL (0), IuUP_ERR_DIST_FIRST_FW (1), IuUP_ERR_DIST_SECOND_FW (2), IuUP_ERR_DIST_RESERVED (3) } with { variant "FIELDLENGTH(2)" }; /* See TS 25.415 6.6.3.16 */ type enumerated IuUP_ErrorCause { /* Syntactical protocol errors */ IuUP_CAUSE_CRC_ERROR_HEADER (0), IuUP_CAUSE_CRC_ERROR_PAYLOAD (1), IuUP_CAUSE_UNEXP_FRAME_NR (2), IuUP_CAUSE_FRAME_LOSS (3), IuUP_CAUSE_PDU_TYPE_UNKNOWN (4), IuUP_CAUSE_UNKNOWN_PROCEDURE (5), IuUP_CAUSE_UNKNOWN_RES_VAL (6), IuUP_CAUSE_UNKNOWN_FIELD (7), IuUP_CAUSE_FRAME_TOO_SHORT (8), IuUP_CAUSE_MISSING_FIELD (9), /* Semantical protocol errors */ IuUP_CAUSE_UNEXPECTED_PDU_TYPE (16), IuUP_CAUSE_UNEXPECTED_PROCEDURE (18), IuUP_CAUSE_UNEXPECTED_RFCI (19), IuUP_CAUSE_UNEXPECTED_VALUE (20), /* Other Errors */ IuUP_CAUSE_INIT_FAIL (42), IuUP_CAUSE_INIT_FAIL_NET_TMR_EXP (43), IuUP_CAUSE_INIT_FAIL_FERR_REP_NACK (44), IuUP_CAUSE_RATE_CONTROL_FAIL (45), IuUP_CAUSE_ERROR_EVENT_FAIL (46), IuUP_CAUSE_TIME_ALIGN_NOTSUPP (47), IuUP_CAUSE_REQ_ALIGN_NOTPOSS (48), IuUP_CAUSE_IU_UP_VERS_NOTSUPP (49) } with { variant "FIELDLENGTH(6)" }; /* See TS 25.415 6.6.3.18 */ type uint8_t IuUP_TimeAlignment; /* See TS 25.415 6.6.3.24 */ type uint4_t IuUP_IPTI; /* See TS 25.415 6.6.2.1 */ type record IuUP_PDU_Type_0 { IuUP_PDU_Type pdu_type, /* 0 */ IuUP_FrameNr frame_nr, IuUP_FQC fqc, IuUP_RFCI rfci, uint6_t header_crc, uint10_t payload_crc, octetstring payload }; /* See TS 25.415 6.6.2.2 */ type record IuUP_PDU_Type_1 { IuUP_PDU_Type pdu_type, /* 1 */ IuUP_FrameNr frame_nr, IuUP_FQC fqc, IuUP_RFCI rfci, uint6_t header_crc, BIT2 spare, octetstring payload }; /* See TS 25.415 6.6.6.2.3 */ type record IuUP_PDU_Type_14 { IuUP_PDU_Type pdu_type, IuUP_AckNack ack_nack, uint2_t frame_nr, IuUP_PDU14_Union u } with { variant (u) "CROSSTAG(proc, ack_nack=IuUP_ACKNACK_CTRL; ack, ack_nack=IuUP_ACKNACK_ACK; nack, ack_nack=IuUP_ACKNACK_NACK)" }; type record IuUP_PDU_Type_14_Common_Hdr { uint4_t iuup_version, IuUP_ProcedureIndicator procedure_ind, uint6_t header_crc, uint10_t payload_crc }; type union IuUP_PDU14_Union { IuUP_PDU14_ProcSending proc, IuUP_PDU14_ACK ack, IuUP_PDU14_NACK nack }; /* 6.6.2.3.1 Figure 21 */ type record IuUP_PDU14_ProcSending { IuUP_PDU_Type_14_Common_Hdr hdr, IuUP_PDU14_ProcSendingUnion u } with { variant (u) "CROSSTAG(init, hdr.procedure_ind=IuUP_PRI_INITIALIZATION; rate_ctrl, hdr.procedure_ind=IuUP_PRI_RATE_CONTROL; time_alignment, hdr.procedure_ind=IuUP_PRI_TIME_ALIGNMENT; error_event, hdr.procedure_ind=IuUP_PRI_ERROR_EVENT; other, OTHERWISE)" }; /* 6.6.2.3.2 Figure 22 */ type record IuUP_PDU14_ACK { IuUP_PDU_Type_14_Common_Hdr hdr, octetstring spare_ext optional }; /* 6.6.2.3.3 Figure 23 */ type record IuUP_PDU14_NACK { IuUP_PDU_Type_14_Common_Hdr hdr, IuUP_ErrorCause err_cause, BIT2 spare, octetstring spare_ext optional }; type union IuUP_PDU14_ProcSendingUnion { IuUP_PDU14_ProcSending_INIT init, IuUP_PDU14_ProcSending_RATE_CTRL rate_ctrl, IuUP_PDU14_ProcSending_TIME_ALIGNMENT time_alignment, IuUP_PDU14_ProcSending_ERROR_EVENT error_event, octetstring other }; /* 6.6.2.3.4.1 Initialisation */ type record IuUP_PDU14_ProcSending_INIT { BIT3 spare, boolean ti, uint3_t subflows_per_rfci, boolean chain_ind, IuUP_InitRfci rfci, IuUP_IPTI_List IPTIs optional, BIT16 versions_supported, uint4_t data_pdu_type, BIT4 spare2 } with { variant (IPTIs) "PRESENCE(ti=true)" variant (versions_supported) "BITORDER(lsb)" variant (versions_supported) "BYTEORDER(last)" }; type record IuUP_InitRfci { boolean lri, boolean li, IuUP_RFCI rfci_id, RecOfU8 len8 optional, RecOfU16 len16 optional, IuUP_InitRfci rfci optional } with { variant (len8) "PRESENCE(li=false)"; variant (len16) "PRESENCE(li=true)" variant (rfci) "PRESENCE(lri=false)" }; type record of IuUP_IPTI IuUP_IPTI_List with { variant "FIELDLENGTH(3)" variant "PADDING(yes)" }; type record of uint8_t RecOfU8 with { variant "FIELDLENGTH(3)" }; type record of uint16_t RecOfU16 with { variant "FIELDLENGTH(3)" }; type record of IuUP_InitRfci IuUP_InitRfciList; /* 6.6.2.3.4.2.1 Rate Control procedure */ type record IuUP_PDU14_ProcSending_RATE_CTRL { BIT2 spare, uint6_t nr_of_rfci_ind, bitstring rfci_ind } with { variant (nr_of_rfci_ind) "LENGTHTO(rfci_ind)" variant (nr_of_rfci_ind) "UNIT(bits)" }; /* 6.6.2.3.4.3 Time Alignment */ type record IuUP_PDU14_ProcSending_TIME_ALIGNMENT { uint8_t time_alignment, octetstring spare optional }; /* 6.6.2.3.4.4 Error Event */ type record IuUP_PDU14_ProcSending_ERROR_EVENT { IuUP_ErrorDistance distance, IuUP_ErrorCause cause }; type union IuUP_PDU { IuUP_PDU_Type_0 type_0, IuUP_PDU_Type_1 type_1, IuUP_PDU_Type_14 type_14 } with { variant "TAG( type_0, pdu_type = 0; type_1, pdu_type = 1; type_14, pdu_type = 14;)" }; /* hand-written C++ functions */ external function f_enc_IuUP_PDU(in IuUP_PDU msg) return octetstring; external function f_IuUP_compute_crc_header(in octetstring inp) return uint6_t; external function f_IuUP_compute_crc_payload(in octetstring inp) return uint10_t; /* auto-generated */ external function dec_IuUP_PDU(in octetstring stream) return IuUP_PDU with { extension "prototype(convert) decode(RAW)" }; template IuUP_PDU ts_IuUP_INIT_ACK(uint2_t frame_nr, uint4_t version) := { type_14 := { pdu_type := 14, ack_nack := IuUP_ACKNACK_ACK, frame_nr := frame_nr, u := { ack := { hdr := { iuup_version := version, procedure_ind := IuUP_PRI_INITIALIZATION, header_crc := 0, payload_crc := 0 }, spare_ext := omit } } } }; template IuUP_PDU tr_IuUP_INIT_ACK(template uint2_t frame_nr := ?, template uint4_t version := ?) := { type_14 := { pdu_type := 14, ack_nack := IuUP_ACKNACK_ACK, frame_nr := frame_nr, u := { ack := { hdr := { iuup_version := version, procedure_ind := IuUP_PRI_INITIALIZATION, header_crc := ?, payload_crc := ? }, spare_ext := omit } } } }; template (value) IuUP_InitRfci ts_IuUP_InitRfci( template (value) boolean lri, template (value) boolean li, template (value) IuUP_RFCI rfci_id, template (omit) RecOfU8 len8, template (omit) RecOfU16 len16, template (omit) IuUP_InitRfci rfci := omit) := { lri := lri, li := li, rfci_id := rfci_id, len8 := len8, len16 := len16, rfci := rfci } template (value) IuUP_PDU14_ProcSending_INIT ts_IuUP_PDU14_ProcSending_INIT( template (value) boolean ti := true, template (value) uint3_t subflows_per_rfci := 3, template (value) boolean chain_ind := false, template (value) IuUP_InitRfci rfci := ts_IuUP_InitRfci(false, false, 0, {81, 103, 60}, omit, ts_IuUP_InitRfci(false, false, 1, {39, 0, 0}, omit, ts_IuUP_InitRfci(true, false, 2, {0, 0, 0}, omit, omit))), template (omit) IuUP_IPTI_List IPTIs := {1, 7, 1}, template (value) BIT16 versions_supported := '0000000000000001'B, template (value) uint4_t data_pdu_type := 0) := { spare := '000'B, ti := ti, subflows_per_rfci := subflows_per_rfci, chain_ind := chain_ind, rfci := rfci, IPTIs := IPTIs, versions_supported := versions_supported, data_pdu_type := data_pdu_type, spare2 := '0000'B } template (present) IuUP_PDU14_ProcSending_INIT tr_IuUP_PDU14_ProcSending_INIT( template (present) boolean ti := ?, template (present) uint3_t subflows_per_rfci := ?, template (present) boolean chain_ind := ?, template (present) IuUP_InitRfci rfci := ?, template IuUP_IPTI_List IPTIs := *, template (present) BIT16 versions_supported := ?, template (present) uint4_t data_pdu_type := ?) := { spare := '000'B, ti := ti, subflows_per_rfci := subflows_per_rfci, chain_ind := chain_ind, rfci := rfci, IPTIs := IPTIs, versions_supported := versions_supported, data_pdu_type := data_pdu_type, spare2 := '0000'B } template (value) IuUP_PDU ts_IuUP_INIT(template (value) IuUP_PDU14_ProcSending_INIT init, uint2_t frame_nr := 0, uint4_t version := 0) := { type_14 := { pdu_type := 14, ack_nack := IuUP_ACKNACK_CTRL, frame_nr := frame_nr, u := { proc := { hdr := { iuup_version := version, procedure_ind := IuUP_PRI_INITIALIZATION, header_crc := 0, payload_crc := 0 }, u := { init := init } } } } }; template IuUP_PDU tr_IuUP_INIT(template (present) IuUP_PDU14_ProcSending_INIT init := ?, template octetstring payload := ?, template uint2_t frame_nr := ?, template uint4_t version := ?) := { type_14 := { pdu_type := 14, ack_nack := IuUP_ACKNACK_CTRL, frame_nr := frame_nr, u := { proc := { hdr := { iuup_version := version, procedure_ind := IuUP_PRI_INITIALIZATION, header_crc := ?, payload_crc := ? }, u := { init := init } } } } }; template IuUP_PDU ts_IuUP_Type0(IuUP_FrameNr frame_nr, IuUP_RFCI rfci, octetstring payload, IuUP_FQC fqc := IuUP_FQC_GOOD) := { type_0 := { pdu_type := 0, frame_nr := frame_nr, fqc := fqc, rfci := rfci, header_crc := 0, payload_crc := 0, payload := payload } }; template IuUP_PDU tr_IuUP_Type0(template IuUP_FrameNr frame_nr := ?, template IuUP_RFCI rfci := ?, template IuUP_FQC fqc := ?) := { type_0 := { pdu_type := 0, frame_nr := frame_nr, fqc := fqc, rfci := rfci, header_crc := ?, payload_crc := ?, payload := ? } }; template IuUP_PDU ts_IuUP_Type1(IuUP_FrameNr frame_nr, IuUP_RFCI rfci, octetstring payload, IuUP_FQC fqc := IuUP_FQC_GOOD) := { type_1 := { pdu_type := 1, frame_nr := frame_nr, fqc := fqc, rfci := rfci, header_crc := 0, spare := '00'B, payload := payload } }; template IuUP_PDU tr_IuUP_Type1(template IuUP_FrameNr frame_nr := ?, template IuUP_RFCI rfci := ?, template IuUP_FQC fqc := ?) := { type_1 := { pdu_type := 1, frame_nr := frame_nr, fqc := fqc, rfci := rfci, header_crc := ?, spare := ?, payload := ? } }; } with { encode "RAW" ; variant "FIELDORDER(msb)" }