mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
RRC/E1AP: Fix SDAP header mapping in E1AP and test callback header handling
This commit fixes two related issues:
1. SDAP Header Mapping Bug (cucp_cuup_handler.c):
The original code incorrectly mapped SDAP header configuration from
internal E1AP representation to ASN.1 enum values. The internal
representation (`bearer_context_sdap_config_t`) uses true=present/false=absent,
while ASN.1 enum (`E1AP_SDAP_Configuration_t`) uses
0=present/1=absent. The fix correctly inverts the mapping:
- Internal true (1) → ASN.1 0 (present)
- Internal false (0) → ASN.1 1 (absent)
The commit also clarifies internal representation in the stack.
2. Test Overhead Adjustment (nr-cuup-load-test.c):
The change in (1) led to a failure in nr_cuup_functional_test
with assertion: "size % 4 == 0" in recv_ng()
- Changed UL packet overhead from 3 bytes to 2 bytes in sender_thread()
- Before the SDAP fix, the test incorrectly accounted for 3 bytes:
* 2 bytes PDCP header (correct)
* 1 byte SDAP header (incorrectly included)
- After the SDAP fix, SDAP headers are correctly set to absent, so
only 2 bytes (PDCP header) are needed
This ensures the test sends packets with the correct header size,
matching what CU-UP expects after the SDAP configuration fix.
The load test does not enable SDAP headers, therefore the original 3-byte
overhead was possibly a workaround for the SDAP header bug.
With the bug fixed, the test correctly uses 2-byte overhead (PDCP header).
This commit is contained in:
@@ -268,8 +268,8 @@ typedef struct up_params_s {
|
||||
/* IE SDAP Configuration (clause 9.3.1.39 of 3GPP TS 38.463) */
|
||||
typedef struct bearer_context_sdap_config_s {
|
||||
long defaultDRB;
|
||||
long sDAP_Header_UL;
|
||||
long sDAP_Header_DL;
|
||||
bool sDAP_Header_UL;
|
||||
bool sDAP_Header_DL;
|
||||
} bearer_context_sdap_config_t;
|
||||
|
||||
/* IE PDCP Configuration (clause 9.3.1.38 of 3GPP TS 38.463) */
|
||||
|
||||
@@ -192,8 +192,8 @@ static E1AP_SDAP_Configuration_t e1_encode_sdap_config(const bearer_context_sdap
|
||||
{
|
||||
E1AP_SDAP_Configuration_t out = {0};
|
||||
out.defaultDRB = in->defaultDRB ? E1AP_DefaultDRB_true : E1AP_DefaultDRB_false;
|
||||
out.sDAP_Header_UL = in->sDAP_Header_UL;
|
||||
out.sDAP_Header_DL = in->sDAP_Header_DL;
|
||||
out.sDAP_Header_UL = in->sDAP_Header_UL ? E1AP_SDAP_Header_UL_present : E1AP_SDAP_Header_UL_absent;
|
||||
out.sDAP_Header_DL = in->sDAP_Header_DL ? E1AP_SDAP_Header_DL_present : E1AP_SDAP_Header_DL_absent;
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -201,8 +201,8 @@ static E1AP_SDAP_Configuration_t e1_encode_sdap_config(const bearer_context_sdap
|
||||
static bool e1_decode_sdap_config(bearer_context_sdap_config_t *out, const E1AP_SDAP_Configuration_t *in)
|
||||
{
|
||||
out->defaultDRB = in->defaultDRB == E1AP_DefaultDRB_true;
|
||||
out->sDAP_Header_UL = in->sDAP_Header_UL;
|
||||
out->sDAP_Header_DL = in->sDAP_Header_DL;
|
||||
out->sDAP_Header_UL = in->sDAP_Header_UL == E1AP_SDAP_Header_UL_present;
|
||||
out->sDAP_Header_DL = in->sDAP_Header_DL == E1AP_SDAP_Header_DL_present;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -212,8 +212,8 @@ static bool e1_decode_sdap_config(bearer_context_sdap_config_t *out, const E1AP_
|
||||
static bool eq_sdap_config(const bearer_context_sdap_config_t *a, const bearer_context_sdap_config_t *b)
|
||||
{
|
||||
_E1_EQ_CHECK_LONG(a->defaultDRB, b->defaultDRB);
|
||||
_E1_EQ_CHECK_LONG(a->sDAP_Header_UL, b->sDAP_Header_UL);
|
||||
_E1_EQ_CHECK_LONG(a->sDAP_Header_DL, b->sDAP_Header_DL);
|
||||
_E1_EQ_CHECK_INT(a->sDAP_Header_UL, b->sDAP_Header_UL);
|
||||
_E1_EQ_CHECK_INT(a->sDAP_Header_DL, b->sDAP_Header_DL);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,8 +60,11 @@ static void fill_DRB_configList_e1(NR_DRB_ToAddModList_t *DRB_configList, const
|
||||
asn1cCalloc(ie->cnAssociation->choice.sdap_Config, sdap_config);
|
||||
sdap_config->pdu_Session = pdu->sessionId;
|
||||
/* SDAP */
|
||||
sdap_config->sdap_HeaderDL = drb->sdap_config.sDAP_Header_DL;
|
||||
sdap_config->sdap_HeaderUL = drb->sdap_config.sDAP_Header_UL;
|
||||
/* Convert from internal representation to ASN.1 enum:
|
||||
* Internal: false=absent, true=present (or uninitialized=false means absent)
|
||||
* ASN.1: 0=present, 1=absent */
|
||||
sdap_config->sdap_HeaderDL = drb->sdap_config.sDAP_Header_DL ? NR_SDAP_Config__sdap_HeaderDL_present : NR_SDAP_Config__sdap_HeaderDL_absent;
|
||||
sdap_config->sdap_HeaderUL = drb->sdap_config.sDAP_Header_UL ? NR_SDAP_Config__sdap_HeaderUL_present : NR_SDAP_Config__sdap_HeaderUL_absent;
|
||||
sdap_config->defaultDRB = drb->sdap_config.defaultDRB;
|
||||
asn1cCalloc(sdap_config->mappedQoS_FlowsToAdd, FlowsToAdd);
|
||||
for (int j = 0; j < drb->numQosFlow2Setup; j++) {
|
||||
|
||||
@@ -299,8 +299,8 @@ static DRB_nGRAN_to_setup_t fill_e1_drb_to_setup(const drb_t *rrc_drb,
|
||||
drb_ngran.id = rrc_drb->drb_id;
|
||||
|
||||
drb_ngran.sdap_config.defaultDRB = true;
|
||||
drb_ngran.sdap_config.sDAP_Header_UL = session->sdap_config.header_ul_absent ? 1 : 0;
|
||||
drb_ngran.sdap_config.sDAP_Header_DL = session->sdap_config.header_dl_absent ? 1 : 0;
|
||||
drb_ngran.sdap_config.sDAP_Header_UL = session->sdap_config.header_ul_absent ? false : true;
|
||||
drb_ngran.sdap_config.sDAP_Header_DL = session->sdap_config.header_dl_absent ? false : true;
|
||||
|
||||
drb_ngran.pdcp_config = set_bearer_context_pdcp_config(rrc_drb->pdcp_config, um_on_default_drb, redcap_cap);
|
||||
|
||||
|
||||
@@ -418,7 +418,9 @@ static void *sender_thread(void *v)
|
||||
{
|
||||
struct thr_data *d = v;
|
||||
|
||||
size_t oh = d->is_ul ? 3 : 0;
|
||||
// Overhead: PDCP header (2 bytes) for UL packets
|
||||
// SDAP headers are disabled, so only PDCP header is added
|
||||
size_t oh = d->is_ul ? 2 : 0;
|
||||
size_t packet_len = d->data_len + oh;
|
||||
uint8_t buf[packet_len];
|
||||
memset(buf, 0, packet_len);
|
||||
|
||||
Reference in New Issue
Block a user