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.
diff --git a/library/RLCMAC_Types.ttcn b/library/RLCMAC_Types.ttcn
new file mode 100644
index 0000000..f73721c
--- /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)" }