Commit e527b99d authored by Guido Casati's avatar Guido Casati

PDCP Status Information: add enc/dec/cp/eq and test to E1AP lib

Also:
* remove unused oldQosFlows IEs
* adopt new enc/dec functions
* fix missing return in eq_bearer_context_mod_response
parent bc9c59f1
......@@ -283,6 +283,22 @@ typedef struct bearer_context_pdcp_config_s {
bool pDCP_Reestablishment;
} bearer_context_pdcp_config_t;
/* 9.3.1.35 3GPP TS 38.463 */
typedef struct {
// PDCP SN
uint32_t sn;
// HFN
uint32_t hfn;
} e1_pdcp_count_t;
/* 9.3.1.58 3GPP TS 38.463 */
typedef struct {
// UL Count Value
e1_pdcp_count_t ul_count;
// DL Count Value
e1_pdcp_count_t dl_count;
} e1_pdcp_status_info_t;
typedef struct drb_to_setup_s {
long drbId;
bearer_context_pdcp_config_t pdcp_config;
......@@ -384,6 +400,8 @@ typedef struct DRB_nGRAN_to_modify_s {
bearer_context_pdcp_config_t *pdcp_config;
// PDCP SN Status Request (O)
bool pdcp_sn_status_requested;
// PDCP SN Status Information
e1_pdcp_status_info_t *pdcp_status;
// DL UP Transport Layer Information (O) (clause 9.3.1.13, 9.3.2.1)
int numDlUpParam;
up_params_t DlUpParamList[E1AP_MAX_NUM_UP_PARAM];
......@@ -561,9 +579,8 @@ typedef struct DRB_nGRAN_modified_s {
// Flow Failed List (O)
int numQosFlowFailed;
qos_flow_failed_t qosFlowsFailed[E1AP_MAX_NUM_QOS_FLOWS];
// Old QoS Flow List (O)
int numOldQosFlow;
qos_flow_list_t oldQosFlows[E1AP_MAX_NUM_QOS_FLOWS];
// PDCP SN Status Information (0)
e1_pdcp_status_info_t *pdcp_status;
} DRB_nGRAN_modified_t;
typedef struct DRB_nGRAN_failed_s {
......
......@@ -360,6 +360,39 @@ static E1AP_UP_Parameters_t encode_dl_up_parameters(const int numUpParam, const
return out;
}
/** @brief PDCP SN Status Information (9.3.1.58 3GPP TS 38.463) */
static E1AP_PDCP_SN_Status_Information_t encode_pdcp_status_info(const e1_pdcp_status_info_t *in)
{
E1AP_PDCP_SN_Status_Information_t pdcp = {0};
pdcp.pdcpStatusTransfer_DL.hFN = in->dl_count.hfn;
pdcp.pdcpStatusTransfer_DL.pDCP_SN = in->dl_count.sn;
pdcp.pdcpStatusTransfer_UL.countValue.hFN = in->ul_count.hfn;
pdcp.pdcpStatusTransfer_UL.countValue.pDCP_SN = in->ul_count.sn;
return pdcp;
}
/** @brief PDCP SN Status Information (9.3.1.58 3GPP TS 38.463) */
static e1_pdcp_status_info_t decode_pdcp_status_info(const E1AP_PDCP_SN_Status_Information_t* in)
{
e1_pdcp_status_info_t out = {0};
const E1AP_PDCP_Count_t *dl = &in->pdcpStatusTransfer_DL;
const E1AP_PDCP_Count_t *ul = &in->pdcpStatusTransfer_UL.countValue;
out.dl_count.hfn = dl->hFN;
out.dl_count.sn = dl->pDCP_SN;
out.ul_count.hfn = ul->hFN;
out.ul_count.sn = ul->pDCP_SN;
return out;
}
static bool eq_pdcp_info(const e1_pdcp_status_info_t *a, const e1_pdcp_status_info_t *b)
{
_E1_EQ_CHECK_INT(a->dl_count.hfn, b->dl_count.hfn);
_E1_EQ_CHECK_INT(a->dl_count.sn, b->dl_count.sn);
_E1_EQ_CHECK_INT(a->ul_count.hfn, b->ul_count.hfn);
_E1_EQ_CHECK_INT(a->ul_count.sn, b->ul_count.sn);
return true;
}
/**
* @brief Equality check for DRB_nGRAN_to_setup_t
*/
......@@ -1409,6 +1442,11 @@ static E1AP_PDU_Session_Resource_To_Modify_Item_t e1_encode_pdu_session_to_mod_i
asn1cCalloc(drb2Mod->pDCP_SN_Status_Request, pDCP_SN_Status_Request);
*pDCP_SN_Status_Request = E1AP_PDCP_SN_Status_Request_requested;
}
// PDCP Status Information (O)
if (j->pdcp_status) {
asn1cCalloc(drb2Mod->pdcp_SN_Status_Information, pdcp);
*pdcp = encode_pdcp_status_info(j->pdcp_status);
}
// DL UP TNL parameters (O)
if (j->numDlUpParam > 0) {
asn1cCalloc(drb2Mod->dL_UP_Parameters, DL_UP_Param_List);
......@@ -1667,9 +1705,14 @@ static bool e1_decode_pdu_session_to_mod_item(pdu_session_to_mod_t *out, const E
CHECK_E1AP_DEC(e1_decode_sdap_config(drb->sdap_config, drb2Mod->sDAP_Configuration));
}
// PDCP SN Status Request (O)
if (drb2Mod->pDCP_SN_Status_Request) {
if (drb2Mod->pDCP_SN_Status_Request && *drb2Mod->pDCP_SN_Status_Request == E1AP_PDCP_SN_Status_Request_requested) {
drb->pdcp_sn_status_requested = true;
}
// PDCP SN Status Information (O)
if (drb2Mod->pdcp_SN_Status_Information) {
drb->pdcp_status = malloc_or_fail(sizeof(*drb->pdcp_status));
*drb->pdcp_status = decode_pdcp_status_info(drb2Mod->pdcp_SN_Status_Information);
}
// DL UP TNL parameters (O)
if (drb2Mod->dL_UP_Parameters) {
E1AP_UP_Parameters_t *dl_up_paramList = drb2Mod->dL_UP_Parameters;
......@@ -1843,6 +1886,7 @@ static DRB_nGRAN_to_mod_t cp_drb_to_mod_item(const DRB_nGRAN_to_mod_t *msg)
cp = *msg;
_E1_CP_OPTIONAL_IE(&cp, msg, sdap_config);
_E1_CP_OPTIONAL_IE(&cp, msg, pdcp_config);
_E1_CP_OPTIONAL_IE(&cp, msg, pdcp_status);
return cp;
}
......@@ -1904,12 +1948,15 @@ static bool eq_drb_to_mod(const DRB_nGRAN_to_mod_t *a, const DRB_nGRAN_to_mod_t
_E1_EQ_CHECK_INT(a->numDlUpParam, b->numDlUpParam);
for (int i = 0; i < a->numDlUpParam; i++) {
_E1_EQ_CHECK_INT(a->DlUpParamList[i].cell_group_id, b->DlUpParamList[i].cell_group_id);
eq_up_tl_info(&a->DlUpParamList[i].tl_info, &b->DlUpParamList[i].tl_info);
result &= eq_up_tl_info(&a->DlUpParamList[i].tl_info, &b->DlUpParamList[i].tl_info);
}
if (a->pdcp_config && b->pdcp_config)
result &= eq_pdcp_config(a->pdcp_config, b->pdcp_config);
if (a->sdap_config && b->sdap_config)
result &= eq_sdap_config(a->sdap_config, b->sdap_config);
_E1_EQ_CHECK_OPTIONAL_PTR(a, b, pdcp_status);
if (a->pdcp_status && b->pdcp_status)
result &= eq_pdcp_info(a->pdcp_status, b->pdcp_status);
return result;
}
......@@ -1984,6 +2031,7 @@ static void free_drb_to_mod_item(const DRB_nGRAN_to_mod_t *msg)
{
free(msg->pdcp_config);
free(msg->sdap_config);
free(msg->pdcp_status);
}
/* Free PDU Session to modify item */
......@@ -2111,6 +2159,13 @@ struct E1AP_E1AP_PDU *encode_E1_bearer_context_mod_response(const e1ap_bearer_mo
asn1cSequenceAdd(drb_mod->flow_Failed_List->list, E1AP_QoS_Flow_Failed_Item_t, fail);
encode_qos_flow_failed_item(fail, &drb->qosFlowsFailed[q]);
}
// PDCP Status Information (O)
if (drb->pdcp_status) {
asn1cCalloc(drb_mod->pDCP_SN_Status_Information, pdcp);
*pdcp = encode_pdcp_status_info(drb->pdcp_status);
}
// UL UP Parameters (O)
if (drb->numUpParam)
drb_mod->uL_UP_Transport_Parameters = calloc_or_fail(1, sizeof(*drb_mod->uL_UP_Transport_Parameters));
......@@ -2310,6 +2365,11 @@ bool decode_E1_bearer_context_mod_response(e1ap_bearer_modif_resp_t *out, const
drbMod->qosFlowsFailed[i] = decode_qos_flow_failed_item(drbIE->flow_Failed_List->list.array[i]);
}
}
// PDCP Status Info (O)
if (drbIE->pDCP_SN_Status_Information) {
drbMod->pdcp_status = malloc_or_fail(sizeof(*drbMod->pdcp_status));
*drbMod->pdcp_status = decode_pdcp_status_info(drbIE->pDCP_SN_Status_Information);
}
}
}
// DRB Failed to Mod list
......@@ -2347,8 +2407,12 @@ e1ap_bearer_modif_resp_t cp_bearer_context_mod_response(const e1ap_bearer_modif_
// Shallow copy
cp = *msg;
// Deep copy PDU sessions modified items
for (int i = 0; i < msg->numPDUSessionsMod; i++)
for (int i = 0; i < msg->numPDUSessionsMod; i++) {
cp.pduSessionMod[i] = cp_pdu_session_mod_item(&msg->pduSessionMod[i]);
for (int j = 0; j < msg->pduSessionMod[i].numDRBModified; j++) {
_E1_CP_OPTIONAL_IE(&cp.pduSessionMod[i].DRBnGRanModList[j], &msg->pduSessionMod[i].DRBnGRanModList[j], pdcp_status);
}
}
return cp;
}
......@@ -2359,6 +2423,8 @@ bool eq_bearer_context_mod_response(const e1ap_bearer_modif_resp_t *a, const e1a
{
if (!a || !b) return false; // Null-check both inputs
bool result = true;
// Basic members
_E1_EQ_CHECK_INT(a->gNB_cu_cp_ue_id, b->gNB_cu_cp_ue_id);
_E1_EQ_CHECK_INT(a->gNB_cu_up_ue_id, b->gNB_cu_up_ue_id);
......@@ -2375,7 +2441,7 @@ bool eq_bearer_context_mod_response(const e1ap_bearer_modif_resp_t *a, const e1a
_E1_EQ_CHECK_OPTIONAL_PTR(pduA, pduB, ng_DL_UP_TL_info);
if (pduA->ng_DL_UP_TL_info && pduB->ng_DL_UP_TL_info)
eq_up_tl_info(pduA->ng_DL_UP_TL_info, pduB->ng_DL_UP_TL_info);
result &= eq_up_tl_info(pduA->ng_DL_UP_TL_info, pduB->ng_DL_UP_TL_info);
// DRB Modified List
_E1_EQ_CHECK_INT(pduA->numDRBModified, pduB->numDRBModified);
......@@ -2387,6 +2453,10 @@ bool eq_bearer_context_mod_response(const e1ap_bearer_modif_resp_t *a, const e1a
for (int j = 0; j < drbModA->numQosFlowSetup; j++) {
_E1_EQ_CHECK_LONG(drbModA->qosFlows[j].qfi, drbModB->qosFlows[j].qfi);
}
_E1_EQ_CHECK_OPTIONAL_PTR(drbModA, drbModB, pdcp_status);
if (drbModA->pdcp_status && drbModB->pdcp_status) {
result &= eq_pdcp_info(drbModA->pdcp_status, drbModA->pdcp_status);
}
}
// DRB Failed to Modify List
......@@ -2420,7 +2490,7 @@ bool eq_bearer_context_mod_response(const e1ap_bearer_modif_resp_t *a, const e1a
}
return true;
return result;
}
/**
......@@ -2432,6 +2502,9 @@ void free_e1ap_context_mod_response(const e1ap_bearer_modif_resp_t *msg)
free(msg->pduSessionMod[i].confidentialityProtectionIndication);
free(msg->pduSessionMod[i].integrityProtectionIndication);
free(msg->pduSessionMod[i].ng_DL_UP_TL_info);
for (int j = 0; j < msg->pduSessionMod[i].numDRBModified; j++) {
free(msg->pduSessionMod[i].DRBnGRanModList[j].pdcp_status);
}
}
}
......
......@@ -490,6 +490,13 @@ static void test_bearer_context_modification_request(void)
.qos_params.qos_characteristics.non_dynamic.fiveqi = 9,
};
const e1_pdcp_status_info_t dummy_pdcp_status = {
.dl_count.hfn = 12,
.dl_count.sn = 34,
.ul_count.hfn = 56,
.ul_count.sn = 78,
};
DRB_nGRAN_to_mod_t drb_to_mod = {
.numDlUpParam = 1,
.DlUpParamList[0].cell_group_id = MCG,
......@@ -497,10 +504,12 @@ static void test_bearer_context_modification_request(void)
.id = 1,
.pdcp_config = malloc_or_fail(sizeof(*drb_to_mod.pdcp_config)),
.pdcp_sn_status_requested = true,
.pdcp_status = malloc_or_fail(sizeof(*drb_to_mod.pdcp_status)),
.numQosFlow2Setup = 1,
.qosFlows[0] = dummy_qos_flows,
};
*drb_to_mod.pdcp_config = dummy_pdcp_config;
*drb_to_mod.pdcp_status = dummy_pdcp_status;
pdu_session_to_mod_t pdusession_mod_item = {
.sessionId = 1,
......@@ -592,12 +601,21 @@ const DRB_nGRAN_failed_t dummy_drb_failed = {
*/
static void test_bearer_context_modification_response(void)
{
const e1_pdcp_status_info_t dummy_pdcp_status = {
.dl_count.hfn = 12,
.dl_count.sn = 2,
.ul_count.hfn = 12,
.ul_count.sn = 3,
};
// DRB Modified List
DRB_nGRAN_modified_t drb_mod = {
.id = 1,
.numQosFlowSetup = 1,
.qosFlows[0].qfi = 1,
.pdcp_status = malloc_or_fail(sizeof(*drb_mod.pdcp_status)),
};
*drb_mod.pdcp_status = dummy_pdcp_status;
// DRB Setup List
DRB_nGRAN_setup_t setup = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment