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 { ...@@ -283,6 +283,22 @@ typedef struct bearer_context_pdcp_config_s {
bool pDCP_Reestablishment; bool pDCP_Reestablishment;
} bearer_context_pdcp_config_t; } 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 { typedef struct drb_to_setup_s {
long drbId; long drbId;
bearer_context_pdcp_config_t pdcp_config; bearer_context_pdcp_config_t pdcp_config;
...@@ -384,6 +400,8 @@ typedef struct DRB_nGRAN_to_modify_s { ...@@ -384,6 +400,8 @@ typedef struct DRB_nGRAN_to_modify_s {
bearer_context_pdcp_config_t *pdcp_config; bearer_context_pdcp_config_t *pdcp_config;
// PDCP SN Status Request (O) // PDCP SN Status Request (O)
bool pdcp_sn_status_requested; 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) // DL UP Transport Layer Information (O) (clause 9.3.1.13, 9.3.2.1)
int numDlUpParam; int numDlUpParam;
up_params_t DlUpParamList[E1AP_MAX_NUM_UP_PARAM]; up_params_t DlUpParamList[E1AP_MAX_NUM_UP_PARAM];
...@@ -561,9 +579,8 @@ typedef struct DRB_nGRAN_modified_s { ...@@ -561,9 +579,8 @@ typedef struct DRB_nGRAN_modified_s {
// Flow Failed List (O) // Flow Failed List (O)
int numQosFlowFailed; int numQosFlowFailed;
qos_flow_failed_t qosFlowsFailed[E1AP_MAX_NUM_QOS_FLOWS]; qos_flow_failed_t qosFlowsFailed[E1AP_MAX_NUM_QOS_FLOWS];
// Old QoS Flow List (O) // PDCP SN Status Information (0)
int numOldQosFlow; e1_pdcp_status_info_t *pdcp_status;
qos_flow_list_t oldQosFlows[E1AP_MAX_NUM_QOS_FLOWS];
} DRB_nGRAN_modified_t; } DRB_nGRAN_modified_t;
typedef struct DRB_nGRAN_failed_s { typedef struct DRB_nGRAN_failed_s {
......
...@@ -360,6 +360,39 @@ static E1AP_UP_Parameters_t encode_dl_up_parameters(const int numUpParam, const ...@@ -360,6 +360,39 @@ static E1AP_UP_Parameters_t encode_dl_up_parameters(const int numUpParam, const
return out; 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 * @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 ...@@ -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); asn1cCalloc(drb2Mod->pDCP_SN_Status_Request, pDCP_SN_Status_Request);
*pDCP_SN_Status_Request = E1AP_PDCP_SN_Status_Request_requested; *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) // DL UP TNL parameters (O)
if (j->numDlUpParam > 0) { if (j->numDlUpParam > 0) {
asn1cCalloc(drb2Mod->dL_UP_Parameters, DL_UP_Param_List); 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 ...@@ -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)); CHECK_E1AP_DEC(e1_decode_sdap_config(drb->sdap_config, drb2Mod->sDAP_Configuration));
} }
// PDCP SN Status Request (O) // 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; 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) // DL UP TNL parameters (O)
if (drb2Mod->dL_UP_Parameters) { if (drb2Mod->dL_UP_Parameters) {
E1AP_UP_Parameters_t *dl_up_paramList = 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) ...@@ -1843,6 +1886,7 @@ static DRB_nGRAN_to_mod_t cp_drb_to_mod_item(const DRB_nGRAN_to_mod_t *msg)
cp = *msg; cp = *msg;
_E1_CP_OPTIONAL_IE(&cp, msg, sdap_config); _E1_CP_OPTIONAL_IE(&cp, msg, sdap_config);
_E1_CP_OPTIONAL_IE(&cp, msg, pdcp_config); _E1_CP_OPTIONAL_IE(&cp, msg, pdcp_config);
_E1_CP_OPTIONAL_IE(&cp, msg, pdcp_status);
return cp; 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 ...@@ -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); _E1_EQ_CHECK_INT(a->numDlUpParam, b->numDlUpParam);
for (int i = 0; i < a->numDlUpParam; i++) { for (int i = 0; i < a->numDlUpParam; i++) {
_E1_EQ_CHECK_INT(a->DlUpParamList[i].cell_group_id, b->DlUpParamList[i].cell_group_id); _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) if (a->pdcp_config && b->pdcp_config)
result &= eq_pdcp_config(a->pdcp_config, b->pdcp_config); result &= eq_pdcp_config(a->pdcp_config, b->pdcp_config);
if (a->sdap_config && b->sdap_config) if (a->sdap_config && b->sdap_config)
result &= eq_sdap_config(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; return result;
} }
...@@ -1984,6 +2031,7 @@ static void free_drb_to_mod_item(const DRB_nGRAN_to_mod_t *msg) ...@@ -1984,6 +2031,7 @@ static void free_drb_to_mod_item(const DRB_nGRAN_to_mod_t *msg)
{ {
free(msg->pdcp_config); free(msg->pdcp_config);
free(msg->sdap_config); free(msg->sdap_config);
free(msg->pdcp_status);
} }
/* Free PDU Session to modify item */ /* Free PDU Session to modify item */
...@@ -2111,6 +2159,13 @@ struct E1AP_E1AP_PDU *encode_E1_bearer_context_mod_response(const e1ap_bearer_mo ...@@ -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); asn1cSequenceAdd(drb_mod->flow_Failed_List->list, E1AP_QoS_Flow_Failed_Item_t, fail);
encode_qos_flow_failed_item(fail, &drb->qosFlowsFailed[q]); 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) // UL UP Parameters (O)
if (drb->numUpParam) if (drb->numUpParam)
drb_mod->uL_UP_Transport_Parameters = calloc_or_fail(1, sizeof(*drb_mod->uL_UP_Transport_Parameters)); 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 ...@@ -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]); 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 // DRB Failed to Mod list
...@@ -2347,8 +2407,12 @@ e1ap_bearer_modif_resp_t cp_bearer_context_mod_response(const e1ap_bearer_modif_ ...@@ -2347,8 +2407,12 @@ e1ap_bearer_modif_resp_t cp_bearer_context_mod_response(const e1ap_bearer_modif_
// Shallow copy // Shallow copy
cp = *msg; cp = *msg;
// Deep copy PDU sessions modified items // 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]); 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; return cp;
} }
...@@ -2359,6 +2423,8 @@ bool eq_bearer_context_mod_response(const e1ap_bearer_modif_resp_t *a, const e1a ...@@ -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 if (!a || !b) return false; // Null-check both inputs
bool result = true;
// Basic members // 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_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); _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 ...@@ -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); _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) 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 // DRB Modified List
_E1_EQ_CHECK_INT(pduA->numDRBModified, pduB->numDRBModified); _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 ...@@ -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++) { for (int j = 0; j < drbModA->numQosFlowSetup; j++) {
_E1_EQ_CHECK_LONG(drbModA->qosFlows[j].qfi, drbModB->qosFlows[j].qfi); _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 // DRB Failed to Modify List
...@@ -2420,7 +2490,7 @@ bool eq_bearer_context_mod_response(const e1ap_bearer_modif_resp_t *a, const e1a ...@@ -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) ...@@ -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].confidentialityProtectionIndication);
free(msg->pduSessionMod[i].integrityProtectionIndication); free(msg->pduSessionMod[i].integrityProtectionIndication);
free(msg->pduSessionMod[i].ng_DL_UP_TL_info); 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) ...@@ -490,6 +490,13 @@ static void test_bearer_context_modification_request(void)
.qos_params.qos_characteristics.non_dynamic.fiveqi = 9, .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 = { DRB_nGRAN_to_mod_t drb_to_mod = {
.numDlUpParam = 1, .numDlUpParam = 1,
.DlUpParamList[0].cell_group_id = MCG, .DlUpParamList[0].cell_group_id = MCG,
...@@ -497,10 +504,12 @@ static void test_bearer_context_modification_request(void) ...@@ -497,10 +504,12 @@ static void test_bearer_context_modification_request(void)
.id = 1, .id = 1,
.pdcp_config = malloc_or_fail(sizeof(*drb_to_mod.pdcp_config)), .pdcp_config = malloc_or_fail(sizeof(*drb_to_mod.pdcp_config)),
.pdcp_sn_status_requested = true, .pdcp_sn_status_requested = true,
.pdcp_status = malloc_or_fail(sizeof(*drb_to_mod.pdcp_status)),
.numQosFlow2Setup = 1, .numQosFlow2Setup = 1,
.qosFlows[0] = dummy_qos_flows, .qosFlows[0] = dummy_qos_flows,
}; };
*drb_to_mod.pdcp_config = dummy_pdcp_config; *drb_to_mod.pdcp_config = dummy_pdcp_config;
*drb_to_mod.pdcp_status = dummy_pdcp_status;
pdu_session_to_mod_t pdusession_mod_item = { pdu_session_to_mod_t pdusession_mod_item = {
.sessionId = 1, .sessionId = 1,
...@@ -592,12 +601,21 @@ const DRB_nGRAN_failed_t dummy_drb_failed = { ...@@ -592,12 +601,21 @@ const DRB_nGRAN_failed_t dummy_drb_failed = {
*/ */
static void test_bearer_context_modification_response(void) 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 Modified List
DRB_nGRAN_modified_t drb_mod = { DRB_nGRAN_modified_t drb_mod = {
.id = 1, .id = 1,
.numQosFlowSetup = 1, .numQosFlowSetup = 1,
.qosFlows[0].qfi = 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 Setup List
DRB_nGRAN_setup_t setup = { 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