mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
XNAP: add encode/decode and unit test for Xn RAN Paging
- Add RAN Paging message type definitions, including paging DRX
enumeration (§9.2.3.66) and RAN paging area cell-list
structure (§9.2.3.38)
- Implement encoder and decoder for RAN Paging
RAN Paging (3GPP TS 38.423v16.2.0 §9.1.1.7)
- UE Identity Index Value (M)
- UE RAN Paging Identity (M)
- Paging DRX (M)
- RAN Paging Area (M)
- Add equality check and memory management helpers
- Add required ASN.1 header includes for RAN Paging IEs
- Extend XNAP library unit tests to cover RAN Paging
Reviewed-by: Venkatareddy Akumalla <venkatareddy.akumalla@openairinterface.org>
Signed-off-by: Mohammed Safwan <mohammed.safwan@openairinterface.org>
This commit is contained in:
@@ -400,4 +400,54 @@ typedef struct {
|
||||
xnap_ngran_cgi_t target_cgi;
|
||||
} xnap_handover_success_t;
|
||||
|
||||
/* 3GPP TS 38.423 9.2.3.66 – Paging DRX */
|
||||
typedef enum {
|
||||
XNAP_PAGING_DRX_32 = 0,
|
||||
XNAP_PAGING_DRX_64,
|
||||
XNAP_PAGING_DRX_128,
|
||||
XNAP_PAGING_DRX_256,
|
||||
XNAP_PAGING_DRX_512,
|
||||
XNAP_PAGING_DRX_1024,
|
||||
} xnap_paging_drx_t;
|
||||
|
||||
typedef enum {
|
||||
XNAP_RAN_PAGING_AREA_CELL_LIST = 0,
|
||||
XNAP_RAN_PAGING_AREA_RAN_AREA_ID,
|
||||
} xnap_ran_paging_area_choice_t;
|
||||
|
||||
/* RAN Area ID entry: TAC (M) + optional RANAC */
|
||||
typedef struct {
|
||||
uint32_t tac; /* 24-bit Tracking Area Code (M) */
|
||||
bool ranac_present;
|
||||
uint8_t ranac; /* RAN Area Code 0..255 (O) */
|
||||
} xnap_ran_area_id_t;
|
||||
|
||||
/* 3GPP TS 38.423 9.2.3.38 – RAN Paging Area */
|
||||
typedef struct {
|
||||
plmn_id_t plmn;
|
||||
xnap_ran_paging_area_choice_t choice;
|
||||
union {
|
||||
struct {
|
||||
uint8_t num_cells;
|
||||
uint64_t *cell_ids; /* NR-Cell-Identity, 36-bit values */
|
||||
};
|
||||
struct {
|
||||
uint8_t num_ran_area_ids;
|
||||
xnap_ran_area_id_t *ran_area_ids;
|
||||
};
|
||||
};
|
||||
} xnap_ran_paging_area_t;
|
||||
|
||||
/* 3GPP TS 38.423 9.1.1.7 – RAN Paging */
|
||||
typedef struct {
|
||||
/* UE Identity Index Value – 10-bit index (M) */
|
||||
uint16_t ue_identity_index_value;
|
||||
/* UE RAN Paging Identity – I-RNTI, 40-bit (M) */
|
||||
uint64_t ue_ran_paging_identity;
|
||||
/* Paging DRX (M) */
|
||||
xnap_paging_drx_t paging_drx;
|
||||
/* RAN Paging Area (M) */
|
||||
xnap_ran_paging_area_t ran_paging_area;
|
||||
} xnap_ran_paging_t;
|
||||
|
||||
#endif /* XNAP_MESSAGES_TYPES_H_ */
|
||||
|
||||
@@ -1488,3 +1488,225 @@ void free_xnap_handover_success(xnap_handover_success_t *msg)
|
||||
// Nothing to free
|
||||
UNUSED(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief XnAP RAN Paging encoding
|
||||
*/
|
||||
XNAP_XnAP_PDU_t *encode_xnap_ran_paging(const xnap_ran_paging_t *msg)
|
||||
{
|
||||
XNAP_XnAP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu));
|
||||
|
||||
pdu->present = XNAP_XnAP_PDU_PR_initiatingMessage;
|
||||
asn1cCalloc(pdu->choice.initiatingMessage, initMsg);
|
||||
initMsg->procedureCode = XNAP_ProcedureCode_id_rANPaging;
|
||||
initMsg->criticality = XNAP_Criticality_reject;
|
||||
initMsg->value.present = XNAP_InitiatingMessage__value_PR_RANPaging;
|
||||
|
||||
XNAP_RANPaging_t *out = &initMsg->value.choice.RANPaging;
|
||||
|
||||
/* UE Identity Index Value (M) – 10-bit BIT STRING */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, XNAP_RANPaging_IEs_t, ie1);
|
||||
ie1->id = XNAP_ProtocolIE_ID_id_UEIdentityIndexValue;
|
||||
ie1->criticality = XNAP_Criticality_reject;
|
||||
ie1->value.present = XNAP_RANPaging_IEs__value_PR_UEIdentityIndexValue;
|
||||
XNAP_UEIdentityIndexValue_t *ue_idx = &ie1->value.choice.UEIdentityIndexValue;
|
||||
ue_idx->present = XNAP_UEIdentityIndexValue_PR_indexLength10;
|
||||
BIT_STRING_t *idx_bs = &ue_idx->choice.indexLength10;
|
||||
UEIDENTITYINDEX_TO_BIT_STRING(msg->ue_identity_index_value, idx_bs);
|
||||
|
||||
/* UE RAN Paging Identity (M) – I-RNTI, 40-bit BIT STRING */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, XNAP_RANPaging_IEs_t, ie2);
|
||||
ie2->id = XNAP_ProtocolIE_ID_id_UERANPagingIdentity;
|
||||
ie2->criticality = XNAP_Criticality_ignore;
|
||||
ie2->value.present = XNAP_RANPaging_IEs__value_PR_UERANPagingIdentity;
|
||||
XNAP_UERANPagingIdentity_t *ue_paging_id = &ie2->value.choice.UERANPagingIdentity;
|
||||
ue_paging_id->present = XNAP_UERANPagingIdentity_PR_i_RNTI_full;
|
||||
BIT_STRING_t *rnti_bs = &ue_paging_id->choice.i_RNTI_full;
|
||||
IRNTI_TO_BIT_STRING(msg->ue_ran_paging_identity, rnti_bs);
|
||||
|
||||
/* Paging DRX (M) */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, XNAP_RANPaging_IEs_t, ie3);
|
||||
ie3->id = XNAP_ProtocolIE_ID_id_PagingDRX;
|
||||
ie3->criticality = XNAP_Criticality_ignore;
|
||||
ie3->value.present = XNAP_RANPaging_IEs__value_PR_PagingDRX;
|
||||
ie3->value.choice.PagingDRX = msg->paging_drx;
|
||||
|
||||
/* RAN Paging Area (M) */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, XNAP_RANPaging_IEs_t, ie4);
|
||||
ie4->id = XNAP_ProtocolIE_ID_id_RANPagingArea;
|
||||
ie4->criticality = XNAP_Criticality_reject;
|
||||
ie4->value.present = XNAP_RANPaging_IEs__value_PR_RANPagingArea;
|
||||
XNAP_RANPagingArea_t *paging_area = &ie4->value.choice.RANPagingArea;
|
||||
MCC_MNC_TO_PLMNID(msg->ran_paging_area.plmn.mcc,
|
||||
msg->ran_paging_area.plmn.mnc,
|
||||
msg->ran_paging_area.plmn.mnc_digit_length,
|
||||
&paging_area->pLMN_Identity);
|
||||
if (msg->ran_paging_area.choice == XNAP_RAN_PAGING_AREA_CELL_LIST) {
|
||||
paging_area->rANPagingAreaChoice.present = XNAP_RANPagingAreaChoice_PR_cell_List;
|
||||
asn1cCalloc(paging_area->rANPagingAreaChoice.choice.cell_List, cell_list);
|
||||
for (int i = 0; i < msg->ran_paging_area.num_cells; i++) {
|
||||
asn1cSequenceAdd(cell_list->list, XNAP_NG_RAN_Cell_Identity_t, cell_item);
|
||||
cell_item->present = XNAP_NG_RAN_Cell_Identity_PR_nr;
|
||||
NR_CELL_ID_TO_BIT_STRING(msg->ran_paging_area.cell_ids[i], &cell_item->choice.nr);
|
||||
}
|
||||
} else {
|
||||
paging_area->rANPagingAreaChoice.present = XNAP_RANPagingAreaChoice_PR_rANAreaID_List;
|
||||
asn1cCalloc(paging_area->rANPagingAreaChoice.choice.rANAreaID_List, ran_area_list);
|
||||
for (int i = 0; i < msg->ran_paging_area.num_ran_area_ids; i++) {
|
||||
const xnap_ran_area_id_t *src = &msg->ran_paging_area.ran_area_ids[i];
|
||||
asn1cSequenceAdd(ran_area_list->list, XNAP_RANAreaID_t, ran_area_item);
|
||||
INT24_TO_OCTET_STRING(src->tac, &ran_area_item->tAC);
|
||||
if (src->ranac_present) {
|
||||
ran_area_item->rANAC = calloc_or_fail(1, sizeof(*ran_area_item->rANAC));
|
||||
*ran_area_item->rANAC = src->ranac;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pdu;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief XnAP RAN Paging decoding
|
||||
*/
|
||||
bool decode_xnap_ran_paging(xnap_ran_paging_t *out, const XNAP_XnAP_PDU_t *pdu)
|
||||
{
|
||||
_EQ_CHECK_INT(pdu->present, XNAP_XnAP_PDU_PR_initiatingMessage);
|
||||
AssertError(pdu->choice.initiatingMessage != NULL, return false, "initiatingMessage is NULL");
|
||||
_EQ_CHECK_LONG(pdu->choice.initiatingMessage->procedureCode, XNAP_ProcedureCode_id_rANPaging);
|
||||
_EQ_CHECK_INT(pdu->choice.initiatingMessage->value.present, XNAP_InitiatingMessage__value_PR_RANPaging);
|
||||
|
||||
XNAP_RANPaging_t *in = &pdu->choice.initiatingMessage->value.choice.RANPaging;
|
||||
XNAP_RANPaging_IEs_t *ie;
|
||||
|
||||
XNAP_LIB_FIND_IE(XNAP_RANPaging_IEs_t, ie, &in->protocolIEs.list, XNAP_ProtocolIE_ID_id_UEIdentityIndexValue, true);
|
||||
XNAP_LIB_FIND_IE(XNAP_RANPaging_IEs_t, ie, &in->protocolIEs.list, XNAP_ProtocolIE_ID_id_UERANPagingIdentity, true);
|
||||
XNAP_LIB_FIND_IE(XNAP_RANPaging_IEs_t, ie, &in->protocolIEs.list, XNAP_ProtocolIE_ID_id_PagingDRX, true);
|
||||
XNAP_LIB_FIND_IE(XNAP_RANPaging_IEs_t, ie, &in->protocolIEs.list, XNAP_ProtocolIE_ID_id_RANPagingArea, true);
|
||||
|
||||
for (int i = 0; i < in->protocolIEs.list.count; i++) {
|
||||
DevAssert(in->protocolIEs.list.array[i]);
|
||||
ie = in->protocolIEs.list.array[i];
|
||||
|
||||
switch (ie->id) {
|
||||
case XNAP_ProtocolIE_ID_id_UEIdentityIndexValue: {
|
||||
_EQ_CHECK_INT(ie->value.present, XNAP_RANPaging_IEs__value_PR_UEIdentityIndexValue);
|
||||
const XNAP_UEIdentityIndexValue_t *ue_idx = &ie->value.choice.UEIdentityIndexValue;
|
||||
if (ue_idx->present != XNAP_UEIdentityIndexValue_PR_indexLength10)
|
||||
return false;
|
||||
out->ue_identity_index_value = BIT_STRING_to_uint16(&ue_idx->choice.indexLength10);
|
||||
} break;
|
||||
|
||||
case XNAP_ProtocolIE_ID_id_UERANPagingIdentity: {
|
||||
_EQ_CHECK_INT(ie->value.present, XNAP_RANPaging_IEs__value_PR_UERANPagingIdentity);
|
||||
const XNAP_UERANPagingIdentity_t *ue_paging_id = &ie->value.choice.UERANPagingIdentity;
|
||||
if (ue_paging_id->present != XNAP_UERANPagingIdentity_PR_i_RNTI_full)
|
||||
return false;
|
||||
out->ue_ran_paging_identity = BIT_STRING_to_uint64(&ue_paging_id->choice.i_RNTI_full);
|
||||
} break;
|
||||
|
||||
case XNAP_ProtocolIE_ID_id_PagingDRX: {
|
||||
_EQ_CHECK_INT(ie->value.present, XNAP_RANPaging_IEs__value_PR_PagingDRX);
|
||||
out->paging_drx = ie->value.choice.PagingDRX;
|
||||
} break;
|
||||
|
||||
case XNAP_ProtocolIE_ID_id_RANPagingArea: {
|
||||
_EQ_CHECK_INT(ie->value.present, XNAP_RANPaging_IEs__value_PR_RANPagingArea);
|
||||
const XNAP_RANPagingArea_t *paging_area = &ie->value.choice.RANPagingArea;
|
||||
PLMNID_TO_MCC_MNC(&paging_area->pLMN_Identity,
|
||||
out->ran_paging_area.plmn.mcc,
|
||||
out->ran_paging_area.plmn.mnc,
|
||||
out->ran_paging_area.plmn.mnc_digit_length);
|
||||
switch (paging_area->rANPagingAreaChoice.present) {
|
||||
case XNAP_RANPagingAreaChoice_PR_cell_List: {
|
||||
out->ran_paging_area.choice = XNAP_RAN_PAGING_AREA_CELL_LIST;
|
||||
const XNAP_NG_RAN_Cell_Identity_ListinRANPagingArea_t *cell_list = paging_area->rANPagingAreaChoice.choice.cell_List;
|
||||
out->ran_paging_area.num_cells = cell_list->list.count;
|
||||
out->ran_paging_area.cell_ids = calloc_or_fail(out->ran_paging_area.num_cells, sizeof(uint64_t));
|
||||
for (int j = 0; j < cell_list->list.count; j++) {
|
||||
const XNAP_NG_RAN_Cell_Identity_t *cell = cell_list->list.array[j];
|
||||
if (cell->present != XNAP_NG_RAN_Cell_Identity_PR_nr)
|
||||
return false;
|
||||
BIT_STRING_TO_NR_CELL_IDENTITY(&cell->choice.nr, out->ran_paging_area.cell_ids[j]);
|
||||
}
|
||||
} break;
|
||||
case XNAP_RANPagingAreaChoice_PR_rANAreaID_List: {
|
||||
out->ran_paging_area.choice = XNAP_RAN_PAGING_AREA_RAN_AREA_ID;
|
||||
const XNAP_RANAreaID_List_t *ran_area_list = paging_area->rANPagingAreaChoice.choice.rANAreaID_List;
|
||||
out->ran_paging_area.num_ran_area_ids = ran_area_list->list.count;
|
||||
out->ran_paging_area.ran_area_ids = calloc_or_fail(out->ran_paging_area.num_ran_area_ids, sizeof(xnap_ran_area_id_t));
|
||||
for (int j = 0; j < ran_area_list->list.count; j++) {
|
||||
const XNAP_RANAreaID_t *ran_area = ran_area_list->list.array[j];
|
||||
xnap_ran_area_id_t *dst = &out->ran_paging_area.ran_area_ids[j];
|
||||
OCTET_STRING_TO_INT24(&ran_area->tAC, dst->tac);
|
||||
if (ran_area->rANAC) {
|
||||
dst->ranac_present = true;
|
||||
dst->ranac = *ran_area->rANAC;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
AssertError(0, return false, "Unknown RANPagingAreaChoice.present=%d\n", paging_area->rANPagingAreaChoice.present);
|
||||
}
|
||||
} break;
|
||||
|
||||
case XNAP_ProtocolIE_ID_id_PagingPriority:
|
||||
PRINT_ERROR("XNAP_ProtocolIE_ID_id %ld not handled, skipping\n", ie->id);
|
||||
break;
|
||||
|
||||
case XNAP_ProtocolIE_ID_id_AssistanceDataForRANPaging:
|
||||
PRINT_ERROR("XNAP_ProtocolIE_ID_id %ld not handled, skipping\n", ie->id);
|
||||
break;
|
||||
|
||||
case XNAP_ProtocolIE_ID_id_UERadioCapabilityForPaging:
|
||||
PRINT_ERROR("XNAP_ProtocolIE_ID_id %ld not handled, skipping\n", ie->id);
|
||||
break;
|
||||
|
||||
default:
|
||||
PRINT_ERROR("XNAP_ProtocolIE_ID_id %ld unknown, skipping\n", ie->id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief XnAP RAN Paging equality function
|
||||
*/
|
||||
bool eq_xnap_ran_paging(const xnap_ran_paging_t *a, const xnap_ran_paging_t *b)
|
||||
{
|
||||
_EQ_CHECK_INT(a->ue_identity_index_value, b->ue_identity_index_value);
|
||||
_EQ_CHECK_UINT64(a->ue_ran_paging_identity, b->ue_ran_paging_identity);
|
||||
_EQ_CHECK_INT(a->paging_drx, b->paging_drx);
|
||||
|
||||
if (!eq_xnap_plmn(&a->ran_paging_area.plmn, &b->ran_paging_area.plmn))
|
||||
return false;
|
||||
_EQ_CHECK_INT(a->ran_paging_area.choice, b->ran_paging_area.choice);
|
||||
if (a->ran_paging_area.choice == XNAP_RAN_PAGING_AREA_CELL_LIST) {
|
||||
_EQ_CHECK_INT(a->ran_paging_area.num_cells, b->ran_paging_area.num_cells);
|
||||
for (int i = 0; i < a->ran_paging_area.num_cells; i++)
|
||||
_EQ_CHECK_UINT64(a->ran_paging_area.cell_ids[i], b->ran_paging_area.cell_ids[i]);
|
||||
} else {
|
||||
_EQ_CHECK_INT(a->ran_paging_area.num_ran_area_ids, b->ran_paging_area.num_ran_area_ids);
|
||||
for (int i = 0; i < a->ran_paging_area.num_ran_area_ids; i++) {
|
||||
_EQ_CHECK_UINT32(a->ran_paging_area.ran_area_ids[i].tac, b->ran_paging_area.ran_area_ids[i].tac);
|
||||
_EQ_CHECK_INT(a->ran_paging_area.ran_area_ids[i].ranac_present, b->ran_paging_area.ran_area_ids[i].ranac_present);
|
||||
if (a->ran_paging_area.ran_area_ids[i].ranac_present)
|
||||
_EQ_CHECK_INT(a->ran_paging_area.ran_area_ids[i].ranac, b->ran_paging_area.ran_area_ids[i].ranac);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief XnAP RAN Paging memory management
|
||||
*/
|
||||
void free_xnap_ran_paging(xnap_ran_paging_t *msg)
|
||||
{
|
||||
if (msg->ran_paging_area.choice == XNAP_RAN_PAGING_AREA_CELL_LIST)
|
||||
free(msg->ran_paging_area.cell_ids);
|
||||
else
|
||||
free(msg->ran_paging_area.ran_area_ids);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ XNAP_XnAP_PDU_t *encode_xnap_sn_status_transfer(const xnap_sn_status_transfer_t
|
||||
XNAP_XnAP_PDU_t *encode_xnap_ue_context_release(const xnap_ue_context_release_t *msg);
|
||||
XNAP_XnAP_PDU_t *encode_xnap_handover_cancel(const xnap_handover_cancel_t *msg);
|
||||
XNAP_XnAP_PDU_t *encode_xnap_handover_success(const xnap_handover_success_t *msg);
|
||||
XNAP_XnAP_PDU_t *encode_xnap_ran_paging(const xnap_ran_paging_t *msg);
|
||||
|
||||
bool decode_xnap_handover_request(xnap_handover_req_t *req, const XNAP_XnAP_PDU_t *pdu);
|
||||
bool decode_xnap_handover_request_acknowledge(xnap_handover_req_ack_t *out, const XNAP_XnAP_PDU_t *pdu);
|
||||
@@ -23,6 +24,7 @@ bool decode_xnap_sn_status_transfer(xnap_sn_status_transfer_t *out, const XNAP_X
|
||||
bool decode_xnap_ue_context_release(xnap_ue_context_release_t *out, const XNAP_XnAP_PDU_t *pdu);
|
||||
bool decode_xnap_handover_cancel(xnap_handover_cancel_t *out, const XNAP_XnAP_PDU_t *pdu);
|
||||
bool decode_xnap_handover_success(xnap_handover_success_t *out, const XNAP_XnAP_PDU_t *pdu);
|
||||
bool decode_xnap_ran_paging(xnap_ran_paging_t *out, const XNAP_XnAP_PDU_t *pdu);
|
||||
|
||||
bool eq_xnap_handover_request(const xnap_handover_req_t *a, const xnap_handover_req_t *b);
|
||||
bool eq_xnap_handover_request_acknowledge(const xnap_handover_req_ack_t *a, const xnap_handover_req_ack_t *b);
|
||||
@@ -32,6 +34,7 @@ bool eq_xnap_sn_status_transfer(const xnap_sn_status_transfer_t *a, const xnap_s
|
||||
bool eq_xnap_ue_context_release(const xnap_ue_context_release_t *a, const xnap_ue_context_release_t *b);
|
||||
bool eq_xnap_handover_cancel(const xnap_handover_cancel_t *a, const xnap_handover_cancel_t *b);
|
||||
bool eq_xnap_handover_success(const xnap_handover_success_t *a, const xnap_handover_success_t *b);
|
||||
bool eq_xnap_ran_paging(const xnap_ran_paging_t *a, const xnap_ran_paging_t *b);
|
||||
|
||||
void free_xnap_handover_request(xnap_handover_req_t *msg);
|
||||
void free_xnap_handover_request_acknowledge(xnap_handover_req_ack_t *msg);
|
||||
@@ -40,5 +43,6 @@ void free_xnap_sn_status_transfer(xnap_sn_status_transfer_t *msg);
|
||||
void free_xnap_ue_context_release(xnap_ue_context_release_t *msg);
|
||||
void free_xnap_handover_cancel(xnap_handover_cancel_t *msg);
|
||||
void free_xnap_handover_success(xnap_handover_success_t *msg);
|
||||
void free_xnap_ran_paging(xnap_ran_paging_t *msg);
|
||||
|
||||
#endif // XNAP_GNB_MOBILITY_MANAGEMENT_H_
|
||||
|
||||
@@ -39,5 +39,15 @@
|
||||
#include "XNAP_DRBBStatusTransfer18bitsSN.h"
|
||||
#include "XNAP_DRBBStatusTransfer12bitsSN.h"
|
||||
|
||||
#include "XNAP_UEIdentityIndexValue.h"
|
||||
#include "XNAP_UERANPagingIdentity.h"
|
||||
#include "XNAP_PagingDRX.h"
|
||||
#include "XNAP_RANPagingArea.h"
|
||||
#include "XNAP_RANPagingAreaChoice.h"
|
||||
#include "XNAP_NG-RAN-Cell-Identity-ListinRANPagingArea.h"
|
||||
#include "XNAP_NG-RAN-Cell-Identity.h"
|
||||
#include "XNAP_RANAreaID-List.h"
|
||||
#include "XNAP_RANAreaID.h"
|
||||
|
||||
#endif // XNAP_LIB_INCLUDES_H
|
||||
|
||||
|
||||
@@ -726,6 +726,65 @@ static void test_xn_handover_success(void)
|
||||
printf("%s() successful\n", __func__);
|
||||
}
|
||||
|
||||
/**
|
||||
* 11. XnAP RAN Paging Testing – cell_List and rANAreaID_List variants
|
||||
*/
|
||||
static void test_xn_ran_paging(void)
|
||||
{
|
||||
/* ---------- create message ---------- */
|
||||
plmn_id_t plmn0 = {.mcc = 208, .mnc = 95, .mnc_digit_length = 2};
|
||||
|
||||
uint64_t *cell_ids = calloc_or_fail(3, sizeof(uint64_t));
|
||||
cell_ids[0] = 0x123456789ULL & 0xFFFFFFFFFULL;
|
||||
cell_ids[1] = 0xABCDEF012ULL & 0xFFFFFFFFFULL;
|
||||
cell_ids[2] = 0x100200300ULL & 0xFFFFFFFFFULL;
|
||||
|
||||
xnap_ran_area_id_t *ran_area_ids = calloc_or_fail(2, sizeof(xnap_ran_area_id_t));
|
||||
ran_area_ids[0] = (xnap_ran_area_id_t){.tac = 0x001234, .ranac_present = true, .ranac = 7};
|
||||
ran_area_ids[1] = (xnap_ran_area_id_t){.tac = 0x005678, .ranac_present = false};
|
||||
|
||||
xnap_ran_paging_t cases[] = {
|
||||
{.ue_identity_index_value = 0x2A5,
|
||||
.ue_ran_paging_identity = 0xABCDE01234ULL,
|
||||
.paging_drx = XNAP_PAGING_DRX_128,
|
||||
.ran_paging_area = {.plmn = plmn0,
|
||||
.choice = XNAP_RAN_PAGING_AREA_CELL_LIST,
|
||||
.num_cells = 3,
|
||||
.cell_ids = cell_ids}},
|
||||
{.ue_identity_index_value = 0x155,
|
||||
.ue_ran_paging_identity = 0x1234567890ULL,
|
||||
.paging_drx = XNAP_PAGING_DRX_64,
|
||||
.ran_paging_area = {.plmn = plmn0,
|
||||
.choice = XNAP_RAN_PAGING_AREA_RAN_AREA_ID,
|
||||
.num_ran_area_ids = 2,
|
||||
.ran_area_ids = ran_area_ids}},
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(cases) / sizeof(*cases); i++) {
|
||||
/* ---------- encode ---------- */
|
||||
XNAP_XnAP_PDU_t *xnenc = encode_xnap_ran_paging(&cases[i]);
|
||||
AssertFatal(xnenc != NULL, "encode_xnap_ran_paging failed");
|
||||
XNAP_XnAP_PDU_t *xndec = xnap_encode_decode(xnenc);
|
||||
xnap_msg_free(xnenc);
|
||||
|
||||
/* ---------- decode ---------- */
|
||||
xnap_ran_paging_t decoded = {0};
|
||||
bool ret = decode_xnap_ran_paging(&decoded, xndec);
|
||||
AssertFatal(ret, "decode_xnap_ran_paging failed");
|
||||
xnap_msg_free(xndec);
|
||||
|
||||
/* ---------- equality ---------- */
|
||||
ret = eq_xnap_ran_paging(&cases[i], &decoded);
|
||||
AssertFatal(ret, "XnAP RAN Paging mismatch (case %zu)\n", i);
|
||||
|
||||
/* ---------- cleanup ---------- */
|
||||
free_xnap_ran_paging(&decoded);
|
||||
free_xnap_ran_paging(&cases[i]);
|
||||
}
|
||||
|
||||
printf("%s() successful\n", __func__);
|
||||
}
|
||||
|
||||
int main() {
|
||||
printf("Starting XnAP Library Unit Tests...\n");
|
||||
|
||||
@@ -742,6 +801,7 @@ int main() {
|
||||
test_xn_ue_context_release();
|
||||
test_xn_handover_cancel();
|
||||
test_xn_handover_success();
|
||||
test_xn_ran_paging();
|
||||
|
||||
printf("All XnAP tests passed!\n");
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user