740 lines
19 KiB
Plaintext
740 lines
19 KiB
Plaintext
/* TITAN REW encode/decode definitions for 3GPP TS 44.060 RLC/MAC Blocks */
|
|
|
|
/* (C) 2017-2018 Harald Welte <laforge@gnumonks.org>
|
|
* 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_Types {
|
|
import from General_Types all;
|
|
import from Osmocom_Types all;
|
|
import from GSM_Types all;
|
|
import from RLCMAC_CSN1_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_Nplus21_or_22_mod_2715648 ('10'B),
|
|
RRBP_Nplus26_mod_2715648 ('11'B)
|
|
} with { variant "FIELDLENGTH(2)" };
|
|
|
|
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;
|
|
}
|
|
|
|
type enumerated EgprsHeaderType {
|
|
RLCMAC_HDR_TYPE_1,
|
|
RLCMAC_HDR_TYPE_2,
|
|
RLCMAC_HDR_TYPE_3
|
|
};
|
|
|
|
type enumerated CodingScheme {
|
|
CS_1,
|
|
CS_2,
|
|
CS_3,
|
|
CS_4,
|
|
MCS_0,
|
|
MCS_1,
|
|
MCS_2,
|
|
MCS_3,
|
|
MCS_4,
|
|
MCS_5,
|
|
MCS_6,
|
|
MCS_7,
|
|
MCS_8,
|
|
MCS_9
|
|
//MCS5_7, ?
|
|
// MCS6_9 ?
|
|
};
|
|
|
|
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;
|
|
}
|
|
|
|
/* 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,
|
|
RlcmacDlCtrlMsg 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 payload_type,
|
|
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,
|
|
RlcmacUlCtrlMsg 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 LlcBlockHdr {
|
|
uint6_t length_ind,
|
|
/* 1 = new LLC PDU starts */
|
|
boolean more,
|
|
/* 0 = another extension octet after LLC PDU, 1 = no more extension octets */
|
|
boolean e
|
|
} with {
|
|
variant (e) "FIELDLENGTH(1)"
|
|
encode "RAW"
|
|
};
|
|
|
|
external function enc_LlcBlockHdr(in LlcBlockHdr si) return octetstring
|
|
with { extension "prototype(convert) encode(RAW)" };
|
|
external function dec_LlcBlockHdr(in octetstring stream) return LlcBlockHdr
|
|
with { extension "prototype(convert) decode(RAW)" };
|
|
|
|
type record LlcBlock {
|
|
/* Header is only present if LI field was present */
|
|
LlcBlockHdr hdr optional,
|
|
octetstring payload
|
|
} with { variant "" };
|
|
type record of LlcBlock LlcBlocks;
|
|
|
|
/* TS 44.060 10.2.1 Downlink RLC data block */
|
|
type record DlMacHdrDataExt {
|
|
/* Octet 1 */
|
|
PowerReduction pr,
|
|
BIT1 spare,
|
|
uint4_t tfi, /* 3 or 4? */
|
|
boolean fbi,
|
|
/* Octet 2 */
|
|
uint7_t bsn,
|
|
boolean e
|
|
} with {
|
|
variant (e) "FIELDLENGTH(1)"
|
|
};
|
|
type record DlMacDataHeader {
|
|
DlMacHeader mac_hdr,
|
|
DlMacHdrDataExt hdr_ext
|
|
} with { variant "" };
|
|
type record RlcmacDlDataBlock {
|
|
DlMacDataHeader mac_hdr,
|
|
/* Octet 3..M / N: manual C++ Decoder */
|
|
LlcBlocks blocks
|
|
} with {
|
|
variant ""
|
|
};
|
|
|
|
external function enc_RlcmacDlDataBlock(in RlcmacDlDataBlock si) return octetstring;
|
|
external function dec_RlcmacDlDataBlock(in octetstring stream) return RlcmacDlDataBlock;
|
|
|
|
|
|
/* a single RLC block / LLC-segment */
|
|
type record EgprsLlcBlockHdr {
|
|
uint7_t length_ind,
|
|
/* 0 = another extension octet after LLC PDU, 1 = no more extension octets */
|
|
boolean e
|
|
} with {
|
|
variant (e) "FIELDLENGTH(1)"
|
|
encode "RAW"
|
|
};
|
|
|
|
external function enc_EgprsLlcBlockHdr(in EgprsLlcBlockHdr si) return octetstring
|
|
with { extension "prototype(convert) encode(RAW)" };
|
|
external function dec_EgprsLlcBlockHdr(in octetstring stream) return EgprsLlcBlockHdr
|
|
with { extension "prototype(convert) decode(RAW)" };
|
|
|
|
type record EgprsLlcBlock {
|
|
/* Header is only present if LI field was present */
|
|
EgprsLlcBlockHdr hdr optional,
|
|
octetstring payload
|
|
} with { variant "" };
|
|
type record of EgprsLlcBlock EgprsLlcBlocks;
|
|
|
|
/* TS 44.060 10.3a.1.1 EGPRS downlink RLC data block, manual c++ encoder/decoder */
|
|
type record EgprsDlMacDataHeader {
|
|
EgprsHeaderType header_type, /* Set internally by decoder */
|
|
uint5_t tfi,
|
|
MacRrbp rrbp,
|
|
BIT2 esp,
|
|
uint3_t usf,
|
|
uint14_t bsn1,
|
|
uint8_t bsn2_offset,
|
|
uint2_t pr, /* power reduction */
|
|
uint2_t spb,
|
|
uint4_t cps
|
|
} with { variant "" };
|
|
/* Manual C++ Decoder: */
|
|
type record RlcmacDlEgprsDataBlock {
|
|
EgprsDlMacDataHeader mac_hdr,
|
|
boolean fbi,
|
|
boolean e,
|
|
EgprsLlcBlocks blocks
|
|
} with {
|
|
variant (fbi) "FIELDLENGTH(1)"
|
|
variant (e) "FIELDLENGTH(1)"
|
|
};
|
|
|
|
/* TS 44.060 10.2.2 */
|
|
type record UlMacDataHeader {
|
|
/* Octet 0 */
|
|
MacPayloadType payload_type,
|
|
uint4_t countdown,
|
|
boolean stall_ind,
|
|
boolean retry,
|
|
/* Octet 1 */
|
|
BIT1 spare,
|
|
boolean pfi_ind,
|
|
uint5_t tfi,
|
|
boolean tlli_ind,
|
|
/* Octet 2 */
|
|
uint7_t bsn,
|
|
boolean e
|
|
} with {
|
|
variant (stall_ind) "FIELDLENGTH(1)"
|
|
variant (retry) "FIELDLENGTH(1)"
|
|
variant (pfi_ind) "FIELDLENGTH(1)"
|
|
variant (tlli_ind) "FIELDLENGTH(1)"
|
|
variant (e) "FIELDLENGTH(1)"
|
|
};
|
|
|
|
type record RlcMacUlPfi {
|
|
uint7_t pfi,
|
|
boolean m
|
|
} with {
|
|
variant (m) "FIELDLENGTH(1)"
|
|
};
|
|
|
|
/* TS 44.060 10.3a.1.1 10.3a.4 EGPRS Uplink RLC/MAC header, manual c++ encoder/decoder */
|
|
type record EgprsUlMacDataHeader {
|
|
EgprsHeaderType header_type, /* Set internally by decoder */
|
|
uint5_t tfi,
|
|
uint4_t countdown,
|
|
BIT1 foi_si,
|
|
BIT1 r_ri,
|
|
uint11_t bsn1,
|
|
uint4_t cps,
|
|
boolean pfi_ind,
|
|
BIT1 rsb,
|
|
BIT2 spb
|
|
} with {
|
|
variant (pfi_ind) "FIELDLENGTH(1)"
|
|
};
|
|
/* Manual C++ Decoder: 10.3a.2.1 EGPRS Uplink RLC data block */
|
|
type record RlcmacUlEgprsDataBlock {
|
|
EgprsUlMacDataHeader mac_hdr,
|
|
boolean tlli_ind,
|
|
boolean e,
|
|
/* Octet 3 ... M (optional): manual C++ Decoder */
|
|
GprsTlli tlli optional,
|
|
RlcMacUlPfi pfi optional,
|
|
EgprsLlcBlocks blocks
|
|
} with {
|
|
variant (tlli_ind) "FIELDLENGTH(1)"
|
|
variant (e) "FIELDLENGTH(1)"
|
|
};
|
|
|
|
/* TS 44.060 10.2.2 */
|
|
type record RlcmacUlDataBlock {
|
|
/* MAC header */
|
|
UlMacDataHeader mac_hdr,
|
|
/* Octet 3 ... M (optional): manual C++ Decoder */
|
|
GprsTlli tlli optional,
|
|
RlcMacUlPfi pfi optional,
|
|
LlcBlocks blocks
|
|
} with {
|
|
variant (tlli) "PRESENCE(mac_hdr.tlli_ind = true)"
|
|
variant (pfi) "PRESENCE(mac_hdr.pfi_ind = true)"
|
|
};
|
|
|
|
external function enc_RlcmacUlDataBlock(in RlcmacUlDataBlock si) return octetstring;
|
|
external function dec_RlcmacUlDataBlock(in octetstring stream) return RlcmacUlDataBlock;
|
|
|
|
type union RlcmacUlBlock {
|
|
RlcmacUlDataBlock data,
|
|
RlcmacUlEgprsDataBlock data_egprs,
|
|
RlcmacUlCtrlBlock ctrl
|
|
} with {
|
|
variant "TAG(data, mac_hdr.payload_type = MAC_PT_RLC_DATA;
|
|
ctrl, {mac_hdr.payload_type = MAC_PT_RLCMAC_NO_OPT,
|
|
mac_hdr.payload_type = MAC_PT_RLCMAC_OPT};
|
|
data_egprs, {mac_hdr.header_type = RLCMAC_HDR_TYPE_1,
|
|
mac_hdr.header_type = RLCMAC_HDR_TYPE_2,
|
|
mac_hdr.header_type = RLCMAC_HDR_TYPE_3}
|
|
)"
|
|
};
|
|
|
|
/* as the sub-types (RlcmacDl*Block) are not using the RAW coder, we cannot
|
|
* use auto-generated functions here, as they would decode those sub-types
|
|
* based on the RAW coder, not baed on the manual C++ functions */
|
|
external function enc_RlcmacUlBlock(in RlcmacUlBlock si) return octetstring;
|
|
external function dec_RlcmacUlBlock(in octetstring stream) return RlcmacUlBlock;
|
|
|
|
type union RlcmacDlBlock {
|
|
RlcmacDlDataBlock data,
|
|
RlcmacDlEgprsDataBlock data_egprs,
|
|
RlcmacDlCtrlBlock ctrl
|
|
} with {
|
|
variant "TAG(data, mac_hdr.mac_hdr.payload_type = MAC_PT_RLC_DATA;
|
|
ctrl, {mac_hdr.payload_type = MAC_PT_RLCMAC_NO_OPT,
|
|
mac_hdr.payload_type = MAC_PT_RLCMAC_OPT};
|
|
data_egprs, {mac_hdr.header_type = RLCMAC_HDR_TYPE_1,
|
|
mac_hdr.header_type = RLCMAC_HDR_TYPE_2,
|
|
mac_hdr.header_type = RLCMAC_HDR_TYPE_3}
|
|
)"
|
|
};
|
|
|
|
/* as the sub-types (RlcmacDl*Block) are not using the RAW coder, we cannot
|
|
* use auto-generated functions here, as they would decode those sub-types
|
|
* based on the RAW coder, not baed on the manual C++ functions */
|
|
external function enc_RlcmacDlBlock(in RlcmacDlBlock si) return octetstring;
|
|
external function dec_RlcmacDlBlock(in octetstring stream) return RlcmacDlBlock;
|
|
|
|
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
|
|
}
|
|
|
|
/************************
|
|
* PTCCH/D (Packet Timing Advance Control Channel) message.
|
|
* TODO: add a spec. reference to the message format definition.
|
|
*************************/
|
|
type record PTCCHTimingAdvanceIE {
|
|
BIT1 spare ('0'B),
|
|
uint7_t ta_val
|
|
} with { variant "" };
|
|
type record of PTCCHTimingAdvanceIE PTCCHTimingAdvanceIEs;
|
|
type record PTCCHDownlinkMsg {
|
|
PTCCHTimingAdvanceIEs ta_idx length(16),
|
|
octetstring padding length(7)
|
|
} with { variant "" };
|
|
|
|
external function enc_PTCCHDownlinkMsg(in PTCCHDownlinkMsg si) return octetstring
|
|
with { extension "prototype(convert) encode(RAW)" };
|
|
external function dec_PTCCHDownlinkMsg(in octetstring stream) return PTCCHDownlinkMsg
|
|
with { extension "prototype(convert) decode(RAW)" };
|
|
|
|
template PTCCHDownlinkMsg tr_PTCCHDownlinkMsg(
|
|
template (present) uint7_t tai0_ta := ?,
|
|
template (present) uint7_t tai1_ta := ?,
|
|
template (present) uint7_t tai2_ta := ?,
|
|
template (present) uint7_t tai3_ta := ?,
|
|
template (present) uint7_t tai4_ta := ?,
|
|
template (present) uint7_t tai5_ta := ?,
|
|
template (present) uint7_t tai6_ta := ?,
|
|
template (present) uint7_t tai7_ta := ?,
|
|
template (present) uint7_t tai8_ta := ?,
|
|
template (present) uint7_t tai9_ta := ?,
|
|
template (present) uint7_t tai10_ta := ?,
|
|
template (present) uint7_t tai11_ta := ?,
|
|
template (present) uint7_t tai12_ta := ?,
|
|
template (present) uint7_t tai13_ta := ?,
|
|
template (present) uint7_t tai14_ta := ?,
|
|
template (present) uint7_t tai15_ta := ?
|
|
) := {
|
|
ta_idx := {
|
|
{ spare := '0'B, ta_val := tai0_ta },
|
|
{ spare := '0'B, ta_val := tai1_ta },
|
|
{ spare := '0'B, ta_val := tai2_ta },
|
|
{ spare := '0'B, ta_val := tai3_ta },
|
|
{ spare := '0'B, ta_val := tai4_ta },
|
|
{ spare := '0'B, ta_val := tai5_ta },
|
|
{ spare := '0'B, ta_val := tai6_ta },
|
|
{ spare := '0'B, ta_val := tai7_ta },
|
|
{ spare := '0'B, ta_val := tai8_ta },
|
|
{ spare := '0'B, ta_val := tai9_ta },
|
|
{ spare := '0'B, ta_val := tai10_ta },
|
|
{ spare := '0'B, ta_val := tai11_ta },
|
|
{ spare := '0'B, ta_val := tai12_ta },
|
|
{ spare := '0'B, ta_val := tai13_ta },
|
|
{ spare := '0'B, ta_val := tai14_ta },
|
|
{ spare := '0'B, ta_val := tai15_ta }
|
|
},
|
|
padding := '2B2B2B2B2B2B2B'O
|
|
}
|
|
|
|
|
|
} with { encode "RAW"; variant "FIELDORDER(msb)" }
|