library/RLCMAC: Add partial support for EGPRS data block encoding/decoding

* RlcmacUlBlock and RlcmacDlBlock gain a new union field "egprs_data",
  which is chosen when msg contains an egprs data block. Hence one can
  use same structure for both gprs/egprs data and simply check
  "ischosen(block.data_egprs)" to know whether it contains egprs or gprs
  data block.
* C++ code in RLCMAC_EncDec.cc takes care of encoding and decoding of
  each data header type and exposes a generic ttcn3 struct
  "UlMacDataHeader" and "DlMacDataHeader". Decoded header type can be
  found in mac_hdr.header_type. This can be used t5ogether with CPS to
  get the MCS of the message received. Similarly, the encoder will use the
  same field to know how to encode the ttcn3 structure.
* In RLCMAC_EncDec.cc order of functions has been ordered to split
  between encoding and decoding, and inside these split between Ul and
  Dl messages.
* Only encoding of UL HeaderType3 and decoding of Dl HeaderType3 is
  implemented so far in RLCMAC_EncDec.cc. However, all code is already
  arranged and functions prepared (with FIXME fprintf) to easily add the
  missing header types once needed.
* Actually only the decoding of DL HeaderType3 has been tested to work so far.
  Encoding may still be missing to octet-align the data block after the header.
  All these wil lbe fixed once a test using them exists.

Change-Id: I2bc4f877a5e17c57ffa8cf05565dc8593b45aae8
This commit is contained in:
Pau Espin 2020-04-27 17:32:01 +02:00 committed by laforge
parent fe3ae511e2
commit 372af7a116
2 changed files with 1078 additions and 156 deletions

File diff suppressed because it is too large Load Diff

View File

@ -41,11 +41,18 @@ module RLCMAC_Types {
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,
@ -238,6 +245,52 @@ module RLCMAC_Types {
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 */
@ -268,6 +321,35 @@ module RLCMAC_Types {
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 */
@ -286,11 +368,16 @@ module RLCMAC_Types {
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;
ctrl, mac_hdr.payload_type = MAC_PT_RLCMAC_OPT)"
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
@ -301,11 +388,16 @@ module RLCMAC_Types {
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;
ctrl, mac_hdr.payload_type = MAC_PT_RLCMAC_OPT)"
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
@ -546,6 +638,15 @@ uint3_t usf) := {
}
}
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,