From 484160bf217300452166ec2eda09fed06f93e5aa Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Fri, 28 Jul 2017 13:30:24 +0200 Subject: library: Initial work on GPRS RLC/MAC encoder/decoder For Downlink and Uplink RLC/MAC Control blocks this is already working quite nicely. Data blocks is not working, as their encoding cannot be expressed in TTCN-3 RAW syntax, and a mixture of C++/native and RAW-generated coder will be required. --- library/GSM_SystemInformation.ttcn | 6 +- library/GSM_Types.ttcn | 19 ++ library/Osmocom_Types.ttcn | 1 + library/RLCMAC_CSN1_Types.ttcn | 503 +++++++++++++++++++++++++++++++++++++ library/RLCMAC_Types.ttcn | 200 +++++++++++++++ 5 files changed, 726 insertions(+), 3 deletions(-) create mode 100644 library/RLCMAC_CSN1_Types.ttcn create mode 100644 library/RLCMAC_Types.ttcn (limited to 'library') diff --git a/library/GSM_SystemInformation.ttcn b/library/GSM_SystemInformation.ttcn index 74852d43..90fa4258 100644 --- a/library/GSM_SystemInformation.ttcn +++ b/library/GSM_SystemInformation.ttcn @@ -15,7 +15,7 @@ module GSM_SystemInformation { } with { variant "" }; /* 24.008 10.5.1.1 */ - type uint16_t CellIdentity; + type uint16_t SysinfoCellIdentity; /* 44.018 10.5.2.1b */ type octetstring CellChannelDescription with { variant "FIELDLENGTH(16)" }; @@ -117,7 +117,7 @@ module GSM_SystemInformation { /* 44.018 9.1.35 */ type record SystemInformationType3 { - CellIdentity cell_id, + SysinfoCellIdentity cell_id, LocationAreaIdentification lai, ControlChannelDescription ctrl_chan_desc, CellOptions cell_options, @@ -164,7 +164,7 @@ module GSM_SystemInformation { /* 44.018 9.1.40 */ type record SystemInformationType6 { - CellIdentity cell_id, + SysinfoCellIdentity cell_id, LocationAreaIdentification lai, CellOptionsSacch cell_options, BIT8 ncc_permitted, diff --git a/library/GSM_Types.ttcn b/library/GSM_Types.ttcn index c2051403..72751019 100644 --- a/library/GSM_Types.ttcn +++ b/library/GSM_Types.ttcn @@ -16,6 +16,7 @@ module GSM_Types { type integer GsmRxLev (0..63); type integer GsmTsc (0..7) with { variant "FIELDLENGTH(8)" }; type uint32_t GsmTmsi; + type uint32_t GprsTlli; /* Table 10.4.1 of Section 10.4 / 3GPP TS 44.018 */ type enumerated RrMessageType { @@ -149,6 +150,9 @@ module GSM_Types { type record MaioHsn { } with { variant "" }; + /* TS 24.008 10.5.1.1 */ + type uint16_t CellIdentity; + /* TS 24.008 10.5.1.2 */ type uint4_t CipheringKeySeqNr (0..7); @@ -335,6 +339,21 @@ module GSM_Types { boolean ps_ir } with { variant "" }; + /* 24.008 10.5.5.6 */ + type record DrxParameter { + uint8_t split_pg_cycle_code, + uint4_t drx_cycle_len_coeff, + boolean split_on_ccch, + uint3_t non_drx_timer + } with { variant "" }; + + /* 24.008 10.5.5.15 */ + type record RoutingAreaIdentification { + LocationAreaIdentification lai, + uint8_t rac + } with { variant "" }; + + /* 9.1.18 */ type record ImmediateAssignment { diff --git a/library/Osmocom_Types.ttcn b/library/Osmocom_Types.ttcn index 0c26f02a..484f6d17 100644 --- a/library/Osmocom_Types.ttcn +++ b/library/Osmocom_Types.ttcn @@ -1,6 +1,7 @@ module Osmocom_Types { type integer uint8_t (0..255) with { variant "unsigned 8 bit" }; type integer uint16_t (0..65535) with { variant "unsigned 16 bit" }; + type integer uint24_t (0..16777215) with { variant "unsigned 24 bit" }; type integer uint32_t (0..4294967295) with { variant "unsigned 32 bit" }; type integer int8_t (-128..127) with { variant "8 bit" }; diff --git a/library/RLCMAC_CSN1_Types.ttcn b/library/RLCMAC_CSN1_Types.ttcn new file mode 100644 index 00000000..b5cc5727 --- /dev/null +++ b/library/RLCMAC_CSN1_Types.ttcn @@ -0,0 +1,503 @@ +/* GPRS RLC/MAC Control Messages as per 3GPP TS 44.060 manually transcribed from the CSN.1 syntax, as no CSN.1 + * tool for Eclipse TITAN could be found. Implements only the minimum necessary messages for Osmocom teseting + * purposes. + * (C) 2017 by Harald Welte */ +module RLCMAC_CSN1_Types { + import from General_Types all; + import from Osmocom_Types all; + import from GSM_Types all; + + /* TS 44.060 11.2.0.1 */ + type enumerated RlcmacDlCtrlMsgType { + PACKET_ACCESS_REJECT ('100001'B), + PACKET_CELL_CHANGE_ORDER ('000001'B), + PACKET_DL_ASSIGNMENT ('000010'B), + PACKET_MEASUREMENT_ORDER ('000011'B), + PACKET_PAGING_REQUEST ('100010'B), + PACKET_PDCH_RELEASE ('100011'B), + PACKET_POLLING_REQUEST ('000100'B), + /* TODO */ + PACKET_TBF_RELEASE ('001000'B), + PACKET_UL_ACK_NACK ('001001'B), + PACKET_UL_ASSIGNMENT ('001010'B), + PACKET_DL_DUMMY_CTRL ('100101'B) + } with { variant "FIELDLENGTH(6)" }; + + /* TS 44.060 11.2.0.2 */ + type enumerated RlcmacUlCtrlMsgType { + PACKET_CELL_CHANGE_FEATURE ('000000'B), + PACKET_CONTROL_ACK ('000001'B), + PACKET_DL_ACK_NACK ('000010'B), + PACKET_UL_DUMMY_CTRL ('000011'B), + PACKET_MEASUREMENT_REPORT ('000100'B), + PACKET_ENH_MEASUREMENT_REPORT ('001010'B), + PACKET_RESOURCE_REQUEST ('000101'B), + PACKET_MOBILE_TBF_STATUS ('000110'B), + PACKET_PSI_STATUS ('000111'B), + PACKET_EGPRS_DL_ACK_NACK ('001000'B), + PACKET_PAUSE ('001001'B), + ADDITIONAL_MS_RA_CAPABILITIES ('001011'B), + PACKET_CELL_CANGE_NOTIFICATION ('001100'B), + PACKET_SI_STATUS ('001101'B), + PACKET_CS_REQUEST ('001110'B), + MBMS_SERVICE_REQUEST ('001111'B), + MBMS_DL_ACK_NACK ('010000'B) + } with { variant "FIELDLENGTH(6)" }; + + type record NullGlobalTfi { + BIT1 presence ('0'B), + GlobalTfi global_tfi + } with { variant "" }; + + type record TenTlli { + BIT2 presence ('10'B), + GprsTlli tlli + } with { variant "" }; + + type union GlobalTfiOrTlli { + NullGlobalTfi global_tfi, + TenTlli tlli + }; + + /* 11.2.7 Packet Downlink Assignment */ + type record PacketDlAssignment { + PageMode page_mode, + BIT1 pres1, + PersistenceLevels persistence_levels optional, + GlobalTfiOrTlli tfi_or_tlli + /* TODO */ + } with { + variant (persistence_levels) "PRESENCE(pres1 = '1'B)" + }; + + /* 11.2.29 Packet Uplink Assignment */ + type record O_Gtfi { + BIT1 presence ('0'B), + GlobalTfi global_tfi + } with { variant "" }; + type record IO_Tlli { + BIT2 presence ('10'B), + GprsTlli tlli + } with { variant "" }; + type record IIO_Tqi { + BIT3 presence ('110'B), + PacketRequestReference pkt_req_ref + } with { variant "" }; + type union PktUlAssUnion { + O_Gtfi global_tfi, + IO_Tlli tlli, + IIO_Tqi tqi + } with { + variant "TAG(global_tfi, presence = '0'B; + tlli, presence = '10'B; + tqi, presence = '110'B)" + }; + type record DynamicAllocation { + BIT1 extd_dyn_alloc, + BIT1 p0_present, + uint4_t p0 optional, + BIT1 pr_mode optional, + BIT1 usf_granularity, + BIT1 ul_tfi_ass_present, + uint5_t ul_tfi_assignment optional, + BIT1 reserved ('0'B), + BIT1 tbf_starting_time_present, + StartingFnDesc tbf_starting_time optional, + TsAllocationUnion ts_allocation + } with { + variant (p0) "PRESENCE(p0_present = '1'B)" + variant (pr_mode) "PRESENCE(p0_present = '1'B)" + variant (ul_tfi_assignment) "PRESENCE(ul_tfi_ass_present = '1'B)" + variant (tbf_starting_time) "PRESENCE(tbf_starting_time_present = '1'B)" + }; + type record TsAllocationTs { + BIT1 presence, + uint3_t usf_tn optional + } with { + variant (usf_tn) "PRESENCE(presence = '1'B)" + }; + type record length(8) of TsAllocationTs TsAllocationTsArr; + type record TnGamma { + BIT1 presence, + uint3_t usf_tn optional, + uint5_t gamma_tn optional + } with { + variant (usf_tn) "PRESENCE(presence = '1'B)" + variant (gamma_tn) "PRESENCE(presence = '1'B)" + }; + type record length(8) of TnGamma TnGamma8; + type record TsAllocationPwr { + uint4_t alpha, + TnGamma tn_gamma + } with { variant "" }; + type record TsAllocationUnion { + BIT1 presence, + TsAllocationTsArr ts optional, + TsAllocationPwr ts_with_pwr optional + } with { + variant (ts) "PRESENCE(presence = '0'B)" + variant (ts_with_pwr) "PRESENCE(presence = '1'B)" + }; + type record SingleBlockAllocation { + uint3_t timeslot_nr, + BIT1 alpha_present, + uint4_t alpha optional, + uint5_t gamma_tn, + BIT1 p0_present, + uint4_t p0 optional, + BIT1 reserved ('0'B) optional, + BIT1 pr_mode optional, + StartingFnDesc tbf_starting_time + } with { + variant (alpha) "PRESENCE(alpha_present = '1'B)" + variant (p0) "PRESENCE(p0_present = '1'B)" + variant (reserved) "PRESENCE(p0_present = '1'B)" + variant (pr_mode) "PRESENCE(p0_present = '1'B)" + }; + type record PktUlAssGprs { + ChCodingCommand ch_coding_cmd, + BIT1 tlli_block_chan_coding, + PacketTimingAdvance pkt_ta, + BIT1 freq_par_present, + FrequencyParameters freq_par optional, + BIT2 alloc_present, + DynamicAllocation dyn_block_alloc optional, + SingleBlockAllocation sgl_block_alloc optional + } with { + variant (freq_par) "PRESENCE(freq_par_present = '1'B)" + variant (dyn_block_alloc) "PRESENCE(alloc_present = '01'B)" + variant (sgl_block_alloc) "PRESENCE(alloc_present = '10'B)" + }; + type record PacketUlAssignment { + PageMode page_mode, + BIT1 persistence_levels_present, + PersistenceLevels persistence_levels optional, + PktUlAssUnion identity, + BIT1 is_egprs, /* msg escape */ + PktUlAssGprs gprs optional + } with { + variant (persistence_levels) "PRESENCE(persistence_levels_present = '1'B)" + variant (gprs) "PRESENCE(is_egprs = '0'B)" + }; + + /* 11.2.10 Packet Paging Request */ + type record MobileIdentityLV { + uint4_t len, + octetstring mobile_id + } with { variant (len) "LENGTHTO(mobile_id)" }; + type record PageInfoPs { + BIT1 presence ('0'B), + BIT1 ptmsi_or_mobile_id, + GsmTmsi ptmsi optional, + MobileIdentityLV mobile_identity optional + } with { + variant (ptmsi) "PRESENCE(ptmsi_or_mobile_id = '0'B)" + variant (mobile_identity) "PRESENCE(ptmsi_or_mobile_id = '1'B)" + }; + type record PageInfoCs { + BIT1 presence ('1'B), + BIT1 tmsi_or_mobile_id, + GsmTmsi tmsi optional, + MobileIdentityLV mobile_identity optional, + ChannelNeeded chan_needed, + BIT1 emlpp_prio_present, + uint3_t emlpp_prio optional + } with { + variant (tmsi) "PRESENCE(tmsi_or_mobile_id = '0'B)" + variant (mobile_identity) "PRESENCE(tmsi_or_mobile_id = '1'B)" + variant (emlpp_prio) "PRESENCE(emlpp_prio_present = '1'B)" + }; + type union PageInfo { + PageInfoPs ps, + PageInfoCs cs + }; + type record PacketPagingReq { + PageMode page_mode, + BIT1 persistence_levels_present, + PersistenceLevels persistence_levels optional, + BIT1 nln_present, + uint2_t nln optional + /* TODO: Repeated PageInfo */ + } with { + variant (persistence_levels) "PRESENCE(persistence_levels_present = '1'B)" + variant (nln) "PRESENCE(nln_present = '1'B)" + }; + + /* 11.2.28 Uplink Ack/Nack */ + type enumerated ChCodingCommand { + CH_CODING_CS1 ('00'B), + CH_CODING_CS2 ('01'B), + CH_CODING_CS3 ('10'B), + CH_CODING_CS4 ('11'B) + } with { variant "FIELDLENGTH(2)" }; + type record UlAckNackGprs { + ChCodingCommand ch_coding_cmd, + AckNackDescription ack_nack_desc, + BIT1 cont_res_tlli_present, + GprsTlli cont_res_tlli optional, + BIT1 pkt_ta_present, + PacketTimingAdvance pkt_ta optional, + BIT1 pwr_ctrl_present, + PowerControlParameters pwr_ctrl optional + /* TODO: Extension Bits, Rel5 ,... */ + } with { + variant (cont_res_tlli) "PRESENCE(cont_res_tlli_present = '1'B)" + variant (pkt_ta) "PRESENCE(pkt_ta_present = '1'B)" + variant (pwr_ctrl) "PRESENCE(pwr_ctrl_present = '1'B)" + }; + type record PacketUlAckNack { + PageMode page_mode, + BIT2 msg_excape ('00'B), + uint5_t uplink_tfi, + BIT1 is_egprs ('0'B), /* msg escape */ + UlAckNackGprs gprs optional + /* TODO: EGPRS */ + } with { variant (gprs) "PRESENCE(is_egprs = '0'B)" }; + + /* 11.2.8 Packet Downlink Dummy Control Block */ + type record PacketDlDummy { + PageMode page_mode, + BIT1 persistence_levels_present, + PersistenceLevels persistence_levels optional + } with { + variant (persistence_levels) "PRESENCE(persistence_levels_present = '1'B)" + }; + + /* 11.2.0.1 */ + type union RlcmacDlCtrlUnion { + PacketDlAssignment dl_assignment, + PacketUlAssignment ul_assignment, + PacketPagingReq paging, + PacketUlAckNack ul_ack_nack, + PacketDlDummy dl_dummy + } with { variant "" }; + + type record RlcmacDlCtrlMsg { + RlcmacDlCtrlMsgType msg_type, + RlcmacDlCtrlUnion u + } with { + variant (u) "CROSSTAG(dl_assignment, msg_type = PACKET_DL_ASSIGNMENT; + ul_assignment, msg_type = PACKET_UL_ASSIGNMENT; + paging, msg_type = PACKET_PAGING_REQUEST; + ul_ack_nack, msg_type = PACKET_UL_ACK_NACK; + dl_dummy, msg_type = PACKET_DL_DUMMY_CTRL + )" + }; + + external function enc_RlcmacDlCtrlMsg(in RlcmacDlCtrlMsg si) return octetstring + with { extension "prototype(convert) encode(RAW)" }; + external function dec_RlcmacDlCtrlMsg(in octetstring stream) return RlcmacDlCtrlMsg + with { extension "prototype(convert) decode(RAW)" }; + + + /* 11.2.6 Packet Downlikn Ack/Nack */ + type record ILevel { + BIT1 presence, + uint4_t i_level optional + } with { variant (i_level) "PRESENCE(presence = '1'B)" }; + type record length(8) of ILevel ILevels; + type record ChannelQualityReport { + uint6_t c_value, + uint3_t rxqual, + uint6_t sign_var, + ILevels i_levels + } with { variant "" }; + type record PacketDlAckNack { + uint5_t dl_tfi, + AckNackDescription ack_nack_desc, + BIT1 chreq_desc_presence, + ChannelReqDescription chreq_desc optional, + ChannelQualityReport ch_qual_rep + } with { variant "" }; + + /* 11.2.2 Packet Control Acknowledgement */ + type enumerated CtrlAck { + MS_RCVD_TWO_RLC_SAME_RTI_DIFF_RBSN_NEW_TFI ('00'B), + MS_RCVD_RBSN1_NO_RBSN0 ('01'B), + MS_RCVD_RBSN0_NO_RBSN1 ('10'B), + MS_RCVD_TWO_RLC_SAME_RTI_DIFF_RBSN ('11'B) + } with { variant "FIELDLENGTH(2)" }; + type record PacketCtrlAck { + GprsTlli tlli, + CtrlAck ctrl_ack + /* TODO: Rel5 additions */ + } with { variant "" }; + + /* 1.2.8b Packet Uplink Dummy Control Block */ + type record PacketUlDummy { + GprsTlli tlli + } with { variant "" }; + + /* 11.2.0.2 */ + type union RlcmacUlCtrlUnion { + PacketCtrlAck ctrl_ack, + PacketDlAckNack dl_ack_nack, + PacketUlDummy ul_dummy + } with { variant "" }; + + type record RlcmacUlCtrlMsg { + RlcmacUlCtrlMsgType msg_type, + RlcmacUlCtrlUnion u + } with { + variant (u) "CROSSTAG(ctrl_ack, msg_type = PACKET_CONTROL_ACK; + dl_ack_nack, msg_type = PACKET_DL_ACK_NACK; + ul_dummy, msg_type = PACKET_UL_DUMMY_CTRL + )" + }; + + external function enc_RlcmacUlCtrlMsg(in RlcmacUlCtrlMsg si) return octetstring + with { extension "prototype(convert) encode(RAW)" }; + external function dec_RlcmacUlCtrlMsg(in octetstring stream) return RlcmacUlCtrlMsg + with { extension "prototype(convert) decode(RAW)" }; + + type bitstring ReceivedBlockBitmap length(64) with { variant "BYTEORDER(last)" }; + + /* 12.3 Ack/Nack Description */ + type record AckNackDescription { + BIT1 final_ack, + uint7_t starting_seq_nr, + ReceivedBlockBitmap receive_block_bitmap + } with { variant "" }; + + /* 12.7 Channel Request Description */ + type enumerated RlcMode { + RLC_MODE_ACKNOWLEDGED (0), + RLC_MODE_UNACKNOWLEDGED (1) + } with { variant "FIELDLENGTH(1)" }; + type enumerated LlcPduType { + LLC_PDU_IS_SACK_OR_ACK (0), + LLC_PDU_IS_NOT_SACK_OR_ACK (1) + } with { variant "FIELDLENGTH(1)" }; + type record ChannelReqDescription { + uint4_t peak_tput_class, + uint2_t priority, + RlcMode rlc_mode, + LlcPduType llc_pdu_type, + uint16_t RlcOctetCount + } with { variant "" }; + + /* 12.8 Frequency Parameters */ + type record FreqIndirect { + uint6_t maio, + uint4_t ma_number, + BIT1 change_mark1_present, + uint2_t change_mark1 optional, + BIT1 change_mark2_present, + uint2_t change_mark2 optional + } with { + variant (change_mark1) "PRESENCE(change_mark1_present = '1'B)" + variant (change_mark2) "PRESENCE(change_mark2_present = '1'B)" + }; + type record FreqDirect1 { + uint6_t maio, + GprsMobileAllication mobile_allocation + } + type record FreqDirect2 { + uint6_t maio, + uint6_t hsn, + uint4_t ma_freq_len, + octetstring m1_freq_list + } with { + /* FIXME: this can not be expressed in TTCN-3 ?!? */ + //variant (ma_freq_len) "LENGTHTO(m1_freq_list)+3" + variant (ma_freq_len) "LENGTHTO(m1_freq_list)" + }; + type record FrequencyParameters { + uint3_t tsc, + BIT2 presence, + uint10_t arfcn optional, + FreqIndirect indirect optional, + FreqDirect1 direct1 optional, + FreqDirect2 direct2 optional + } with { + variant (arfcn) "PRESENCE(presence = '00'B)" + variant (indirect) "PRESENCE(presence = '01'B)" + variant (direct1) "PRESENCE(presence = '10'B)" + variant (direct2) "PRESENCE(presence = '11'B)" + }; + + /* 12.10 Global TFI */ + type record GlobalTfi { + boolean is_dl_tfi, + uint5_t tfi + } with { variant (is_dl_tfi) "FIELDLENGTH(1)" }; + + /* 12.10a GPRS Mobile Allocation */ + type record RflNumberList { + uint4_t rfl_number, + BIT1 presence, + RflNumberList rfl_number_list optional + } with { + variant (rfl_number_list) "PRESENCE(presence = '1'B)" + }; + type record GprsMobileAllication { + uint6_t hsn, + BIT1 rfl_number_list_present, + RflNumberList rfl_number_list optional, + BIT1 ma_present, + uint6_t ma_length optional, + bitstring ma_bitmap optional + /* TODO: ARFCN index list */ + } with { + variant (rfl_number_list) "PRESENCE(rfl_number_list_present = '1'B)" + variant (ma_length) "PRESENCE(ma_present = '0'B)" + variant (ma_bitmap) "PRESENCE(ma_present = '0'B)" + /* FIXME: this can not be expressed in TTCN-3 ?!? */ + //variant (ma_length) "LENGTHTO(ma_bitmap)+1" + variant (ma_length) "LENGTHTO(ma_bitmap)" + } + + /* 12.11 Packet Request Reference */ + type record PacketRequestReference { + uint11_t ra_info, + uint16_t frame_nr + } with { variant "" }; + + /* 12.12 Packet Timing Advance */ + type record PacketTimingAdvance { + BIT1 val_present, + uint6_t val optional, + BIT1 idx_present, + uint4_t idx optional, + uint3_t timeslot_nr optional + } with { + variant (val) "PRESENCE(val_present = '1'B)" + variant (idx) "PRESENCE(idx_present = '1'B)" + variant (timeslot_nr) "PRESENCE(idx_present = '1'B)" + }; + + /* 12.13 Power Control Parameters */ + type record ZeroOneGamma { + BIT1 gamma_present, + uint5_t gamma + } with { + variant (gamma) "PRESENCE (gamma_present = '1'B)" + }; + type record length(8) of ZeroOneGamma ZeroOneGammas; + type record PowerControlParameters { + uint4_t alpha, + ZeroOneGammas gamma + } with { variant "" }; + + /* 12.14 Persistence Level */ + type record length(4) of uint4_t PersistenceLevels; + + /* 12.20 Page Mode */ + type enumerated PageMode { + PAGE_MODE_NORMAL ('00'B), + PAGE_MODE_EXTENDED ('01'B), + PAGE_MODE_REORG ('10'B), + PAGE_MODE_SAME ('11'B) + } with { variant "FIELDLENGTH(2)" }; + + /* 12.21 Starting Frame Number */ + type record StartingFnDesc { + BIT1 presence, + uint16_t absolute_starting_time optional, + uint13_t relative_k optional + } with { + variant (absolute_starting_time) "PRESENCE(presence = '0'B)" + variant (relative_k) "PRESENCE(presence = '1'B)" + }; + +} with { encode "RAW"; variant "FIELDORDER(msb)" variant "BYTEORDER(last)" }; diff --git a/library/RLCMAC_Types.ttcn b/library/RLCMAC_Types.ttcn new file mode 100644 index 00000000..f73721c0 --- /dev/null +++ b/library/RLCMAC_Types.ttcn @@ -0,0 +1,200 @@ +/* TITAN REW encode/decode definitions for 3GPP TS 44.060 RLC/MAC Blocks */ +module RLCMAC_Types { + import from General_Types all; + import from Osmocom_Types all; + import from GSM_Types all; + + /* TS 44.060 10.4.7 */ + type enumerated MacPayloadType { + MAC_PT_RLC_DATA ('00'B), + MAC_PT_RLCMAC_NO_OPT ('01'B), + MAC_PT_RLCMAC_OPT ('10'B), + MAC_PT_RESERVED ('11'B) + } with { variant "FIELDLENGTH(2)" }; + + /* TS 44.060 10.4.5 */ + type enumerated MacRrbp { + RRBP_Nplus13_mod_2715648 ('00'B), + RRBP_Nplus17_or_18_mod_2715648 ('01'B), + RRBP_Nplus22_or_22_mod_2715648 ('10'B), + RRBP_Nplus26_mod_2715648 ('11'B) + } with { variant "FIELDLENGTH(2)" }; + + /* Partof DL RLC data block and DL RLC/MAC ctrl block */ + type record DlMacHeader { + MacPayloadType payload_type, + MacRrbp rrbp, + boolean rrbp_valid, + uint3_t usf + } with { + variant (rrbp_valid) "FIELDLENGTH(1)" + }; + + /* TS 44.060 10.4.10a */ + type enumerated PowerReduction { + PWR_RED_0_to_3dB ('00'B), + PWR_RED_3_to_7dB ('01'B), + PWR_RED_7_to_10dB ('10'B), + PWR_RED_RESERVED ('11'B) + } with { variant "FIELDLENGTH(2)" }; + + /* TS 44.060 10.4.9d */ + type enumerated DirectionBit { + DIR_UPLINK_TBF ('0'B), + DIR_DOWNLINK_TBF ('1'B) + } with { variant "FIELDLENGTH(1)" }; + + type record TfiOctet { + /* PR, TFI, D */ + PowerReduction pr, + uint5_t tfi, + DirectionBit d + } with { variant "" }; + + type record RbsnExtOctet { + uint3_t rbsn_e, + BIT1 fs_e, + BIT4 spare + } with { variant "" }; + + type record DlCtrlOptOctets { + /* RBSN, RTI, FS, AC (optional, depending on mac_hdr.payload_type) */ + BIT1 rbsn, + uint5_t rti, + boolean fs, + boolean tfi_octet_present, + TfiOctet tfi optional, + RbsnExtOctet rbsn_ext optional + } with { + variant (fs) "FIELDLENGTH(1)" + variant (tfi_octet_present) "FIELDLENGTH(1)" + variant (tfi) "PRESENCE(tfi_octet_present = true)" + variant (rbsn_ext) "PRESENCE(rbsn='1'B, fs=false)" + }; + + /* TS 44.060 10.3.1 Downlink RLC/MAC control block */ + type record RlcmacDlCtrlBlock { + DlMacHeader mac_hdr, + DlCtrlOptOctets opt optional, + octetstring payload + } with { + variant (opt) "PRESENCE(mac_hdr.payload_type = MAC_PT_RLCMAC_OPT)" + }; + + external function enc_RlcmacDlCtrlBlock(in RlcmacDlCtrlBlock si) return octetstring + with { extension "prototype(convert) encode(RAW)" }; + external function dec_RlcmacDlCtrlBlock(in octetstring stream) return RlcmacDlCtrlBlock + with { extension "prototype(convert) decode(RAW)" }; + + type record UlMacCtrlHeader { + MacPayloadType pt, + BIT5 spare, + boolean retry + } with { variant (retry) "FIELDLENGTH(1)" }; + + /* TS 44.060 10.3.2 UplinkRLC/MAC control block */ + type record RlcmacUlCtrlBlock { + UlMacCtrlHeader mac_hdr, + octetstring payload + } with { variant "" }; + + external function enc_RlcmacUlCtrlBlock(in RlcmacUlCtrlBlock si) return octetstring + with { extension "prototype(convert) encode(RAW)" }; + external function dec_RlcmacUlCtrlBlock(in octetstring stream) return RlcmacUlCtrlBlock + with { extension "prototype(convert) decode(RAW)" }; + + /* a single RLC block / LLC-segment */ + + type record RlcBlockHdr { + uint6_t length_ind, + /* 1 = new LLC PDU starts */ + BIT1 more, + /* 0 = another extension octet after LLC PDU, 1 = no more extension octets */ + BIT1 e + } with { variant "" }; + + type record RlcBlock { + uint6_t length_ind, + BIT1 more, + BIT1 e, + octetstring rlc optional + } with { + variant (rlc) "PRESENCE (more = '1'B)" + variant (length_ind) "LENGTHTO(length_ind, more, e, rlc)" + }; + + type record of RlcBlock RlcBlocks; + + /* TS 44.060 10.2.1 Downlink RLC data block */ + type record RlcmacDlDataBlock { + /* Octet 1 */ + DlMacHeader mac_hdr, + /* Octet 2 */ + PowerReduction pr, + BIT1 spare, + uint4_t tfi, /* 3 or 4? */ + boolean fbi, + /* Octet 3 */ + uint7_t bsn, + BIT1 e ('1'B), + RlcBlocks rlc_blocks + } with { variant "" }; + + external function enc_RlcmacDlDataBlock(in RlcmacDlDataBlock si) return octetstring + with { extension "prototype(convert) encode(RAW)" }; + external function dec_RlcmacDlDataBlock(in octetstring stream) return RlcmacDlDataBlock + with { extension "prototype(convert) decode(RAW)" }; + + + /* TS 44.060 10.2.2 */ + type record UlMacDataHeader { + MacPayloadType pt, + uint4_t countdown, + boolean stall_ind, + boolean retry + } with { + variant (stall_ind) "FIELDLENGTH(1)" + variant (retry) "FIELDLENGTH(1)" + }; + + type record RlcMacUlTlli { + RlcBlockHdr hdr, + uint32_t tlli + } with { + variant "" + } + + type record RlcMacUlPfi { + uint7_t pfi, + boolean m + } with { + variant (m) "FIELDLENGTH(1)" + }; + + /* TS 44.060 10.2.2 */ + type record RlcmacUlDataBlock { + /* MAC header */ + UlMacDataHeader mac_hdr, + /* Octet 1 */ + BIT1 spare, + boolean pfi_ind, + uint5_t tfi, + boolean tlli_ind, + /* Octet 2 */ + uint7_t bsn, + BIT1 e ('1'B), + /* Octet 3 (optional) */ + RlcMacUlTlli tlli, + RlcMacUlPfi pfi, + RlcBlocks blocks + } with { + variant (tlli) "PRESENCE(tlli_ind = true)" + variant (pfi) "PRESENCE(pfi_ind = true)" + }; + + external function enc_RlcmacUlDataBlock(in RlcmacUlDataBlock si) return octetstring + with { extension "prototype(convert) encode(RAW)" }; + external function dec_RlcmacUlDataBlock(in octetstring stream) return RlcmacUlDataBlock + with { extension "prototype(convert) decode(RAW)" }; + +} with { encode "RAW"; variant "FIELDORDER(msb)" } -- cgit v1.2.3