/* TITAN REW encode/decode definitions for 3GPP TS 44.060 RLC/MAC Blocks */ /* (C) 2017-2018 Harald Welte * (C) 2020 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 RLCMAC_Templates { import from General_Types all; import from Osmocom_Types all; import from GSM_Types all; import from RLCMAC_CSN1_Types all; import from RLCMAC_CSN1_Templates all; import from RLCMAC_Types all; /* TS 44.060 10.4.5 */ function f_rrbp_fn_delay(MacRrbp rrbp) return uint32_t { select (rrbp) { case (RRBP_Nplus13_mod_2715648) { return 13; } case (RRBP_Nplus17_or_18_mod_2715648) { return 17; } case (RRBP_Nplus21_or_22_mod_2715648) { return 21; } case (RRBP_Nplus26_mod_2715648) { return 26; } } return 0; } function f_rlcmac_cs_mcs2block_len(CodingScheme cs_mcs) return uint32_t { select (cs_mcs) { case (CS_1) { return 23; } case (CS_2) { return 34; } case (CS_3) { return 40; } case (CS_4) { return 54; } case (MCS_1) { return 27; } case (MCS_2) { return 33; } case (MCS_3) { return 42; } case (MCS_4) { return 49; } case (MCS_5) { return 61; } case (MCS_6) { return 79; } case (MCS_7) { return 119; } case (MCS_8) { return 143; } case (MCS_9) { return 155; } } return 0; } function f_rlcmac_block_len2cs_mcs(uint32_t len) return CodingScheme { select (len) { case (23) { return CS_1; } case (34) { return CS_2; } case (40) { return CS_3; } case (54) { return CS_4; } case (27) { return MCS_1; } case (33) { return MCS_2; } case (42) { return MCS_3; } case (49) { return MCS_4; } case (60) { return MCS_5; } case (61) { return MCS_5; } case (78) { return MCS_6; } case (79) { return MCS_6; } case (118) { return MCS_7; } case (119) { return MCS_7; } case (142) { return MCS_8; } case (143) { return MCS_8; } case (154) { return MCS_9; } case (155) { return MCS_9; } } return CS_1; } template (value) RlcmacUlBlock ts_RLC_UL_CTRL_ACK(RlcmacUlCtrlMsg ctrl, MacPayloadType pt := MAC_PT_RLCMAC_NO_OPT, boolean retry := false) := { ctrl := { mac_hdr := { payload_type := pt, spare := '00000'B, retry := retry }, payload := ctrl } } /* Send Template for Downlink ACK/NACK */ template RlcmacUlBlock ts_RLCMAC_DL_ACK_NACK(template uint5_t tfi, AckNackDescription andesc, boolean retry := false) := { ctrl := { mac_hdr := { payload_type := MAC_PT_RLCMAC_NO_OPT, spare := '00000'B, retry := retry }, payload := { msg_type := PACKET_DL_ACK_NACK, u := { dl_ack_nack := { dl_tfi := tfi, ack_nack_desc := andesc, chreq_desc_presence := '0'B, chreq_desc := omit, ch_qual_rep := c_ChQualRep_default } } } } } /* Template for uplink Data block */ template RlcmacUlBlock t_RLCMAC_UL_DATA(template uint5_t tfi, template uint4_t cv, template uint7_t bsn, template LlcBlocks blocks := {}, template boolean stall := false) := { data := { mac_hdr := { payload_type := MAC_PT_RLC_DATA, countdown := cv, stall_ind := false, retry := false, spare := '0'B, pfi_ind := false, tfi := tfi, tlli_ind := false, bsn := bsn, e := false }, tlli := omit, pfi := omit, blocks := blocks } } template RlcmacUlBlock t_RLCMAC_UL_DATA_TLLI(template uint5_t tfi, template uint4_t cv, template uint7_t bsn, template LlcBlocks blocks := {}, template boolean stall := false, template GprsTlli tlli) := { data := { mac_hdr := { payload_type := MAC_PT_RLC_DATA, countdown := cv, stall_ind := false, retry := false, spare := '0'B, pfi_ind := false, tfi := tfi, tlli_ind := true, bsn := bsn, e := false }, tlli := tlli, pfi := omit, blocks := blocks } } template DlMacHeader t_RLCMAC_DlMacH(template MacPayloadType pt, template MacRrbp rrbp, template uint3_t usf) := { payload_type := pt, rrbp := rrbp, rrbp_valid := ispresent(rrbp), usf := usf } template RlcmacDlBlock tr_RLCMAC_DUMMY_CTRL(template uint3_t usf := ?, template PageMode page_mode := ?) := { ctrl := { mac_hdr := { payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT), rrbp:= ?, rrbp_valid := ?, usf := usf }, opt := *, payload := { msg_type := PACKET_DL_DUMMY_CTRL, u := { dl_dummy := { page_mode := page_mode, persistence_levels_present := ?, persistence_levels := * } } } } } template RlcmacDlBlock tr_RLCMAC_DL_PACKET_ASS(template uint3_t usf := ?) := { ctrl := { mac_hdr := { payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT), rrbp:= ?, rrbp_valid := ?, usf := usf }, opt := *, payload := { msg_type := PACKET_DL_ASSIGNMENT, u := { dl_assignment := { page_mode := ?, pres1 := ?, persistence_levels := *, tfi_or_tlli := ? } } } } } template RlcmacDlBlock tr_RLCMAC_UL_PACKET_ASS(template uint3_t usf := ?) := { ctrl := { mac_hdr := { payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT), rrbp:= ?, rrbp_valid := ?, usf := usf }, opt := *, payload := { msg_type := PACKET_UL_ASSIGNMENT, u := { ul_assignment := { page_mode := ?, persistence_levels_present := ?, persistence_levels := *, identity := ?, is_egprs := ?, /* msg escape */ gprs := * } } } } } /* Receive Template for Uplink ACK/NACK */ template RlcmacDlBlock tr_RLCMAC_UL_ACK_NACK(template uint5_t ul_tfi, template GprsTlli tlli := ?) := { ctrl := { mac_hdr := { payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT), rrbp:= ?, rrbp_valid := ?, usf := ? }, opt := *, payload := { msg_type := PACKET_UL_ACK_NACK, u := { ul_ack_nack := { page_mode := ?, msg_excape := ?, uplink_tfi := ul_tfi, is_egprs := '0'B, gprs := { ch_coding_cmd := ?, ack_nack_desc := ?, cont_res_tlli_present := ?, cont_res_tlli := tlli, pkt_ta_present := ?, pkt_ta := *, pwr_ctrl_present := ?, pwr_ctrl := * } } } } } } template RlcmacDlBlock tr_RLCMAC_PACKET_PAG_REQ(template uint3_t usf := ?) := { ctrl := { mac_hdr := { payload_type := MAC_PT_RLCMAC_NO_OPT, rrbp:= ?, rrbp_valid := ?, usf := usf }, opt := *, payload := { msg_type := PACKET_PAGING_REQUEST, u := { paging := { page_mode := ?, persistence_levels_present := ?, persistence_levels := *, nln_present := ?, nln := *, repeated_pageinfo_present := ?, repeated_pageinfo := * } } } } } template RlcmacDlBlock tr_RLCMAC_DATA_RRBP := { data := { mac_hdr := { mac_hdr := { payload_type := MAC_PT_RLC_DATA, rrbp := ?, rrbp_valid := true, usf := ? }, hdr_ext := ? }, blocks := ? } } template RlcmacDlBlock tr_RLCMAC_DATA_EGPRS := { data_egprs := { mac_hdr := ?, fbi := ?, e := ?, blocks := ? } } /* Template for Uplink MAC Control Header */ template UlMacCtrlHeader t_RLCMAC_UlMacCtrlH(template MacPayloadType pt, template boolean retry := false) := { payload_type := pt, spare := '00000'B, retry := retry } /* Template for Uplink Control ACK */ template RlcmacUlBlock ts_RLCMAC_CTRL_ACK(GprsTlli tlli, CtrlAck ack := MS_RCVD_TWO_RLC_SAME_RTI_DIFF_RBSN) := { ctrl := { mac_hdr := t_RLCMAC_UlMacCtrlH(MAC_PT_RLCMAC_NO_OPT), payload := { msg_type := PACKET_CONTROL_ACK, u := { ctrl_ack := { tlli := tlli, ctrl_ack := ack } } } } } /* Template for a LlcBlock (part of a LLC frame inside RlcMac?lDataBlock */ template LlcBlock t_RLCMAC_LLCBLOCK(octetstring data, boolean more := false, boolean e := true) := { /* let encoder figure out the header */ hdr := omit, payload := data } } with { encode "RAW"; variant "FIELDORDER(msb)" }