Add encoding/decoding lib for F1AP DL RRC Transfer message
This commit is contained in:
@@ -197,3 +197,165 @@ void free_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *m
|
||||
free(msg->rrc_container);
|
||||
free(msg->du2cu_rrc_container);
|
||||
}
|
||||
|
||||
/* ============================
|
||||
* F1AP DL RRC Message Transfer
|
||||
* ============================ */
|
||||
|
||||
/**
|
||||
* @brief DL RRC Message Transfer encoding (9.2.3.2 of 3GPP TS 38.473)
|
||||
* gNB-CU → gNB-DU
|
||||
*/
|
||||
F1AP_F1AP_PDU_t *encode_dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *msg)
|
||||
{
|
||||
F1AP_F1AP_PDU_t *pdu = calloc(1, sizeof(*pdu));
|
||||
AssertFatal(pdu != NULL, "out of memory\n");
|
||||
|
||||
/* Create */
|
||||
/* 0. Message Type */
|
||||
pdu->present = F1AP_F1AP_PDU_PR_initiatingMessage;
|
||||
asn1cCalloc(pdu->choice.initiatingMessage, tmp);
|
||||
tmp->procedureCode = F1AP_ProcedureCode_id_DLRRCMessageTransfer;
|
||||
tmp->criticality = F1AP_Criticality_ignore;
|
||||
tmp->value.present = F1AP_InitiatingMessage__value_PR_DLRRCMessageTransfer;
|
||||
F1AP_DLRRCMessageTransfer_t *out = &tmp->value.choice.DLRRCMessageTransfer;
|
||||
// gNB-CU UE F1AP ID (M)
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie1);
|
||||
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
|
||||
ie1->criticality = F1AP_Criticality_reject;
|
||||
ie1->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_CU_UE_F1AP_ID;
|
||||
ie1->value.choice.GNB_CU_UE_F1AP_ID = msg->gNB_CU_ue_id;
|
||||
// gNB-DU UE F1AP ID (M)
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie2);
|
||||
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
|
||||
ie2->criticality = F1AP_Criticality_reject;
|
||||
ie2->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID;
|
||||
ie2->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id;
|
||||
// old gNB-DU UE F1AP ID (O)
|
||||
if (msg->old_gNB_DU_ue_id) {
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie3);
|
||||
ie3->id = F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID;
|
||||
ie3->criticality = F1AP_Criticality_reject;
|
||||
ie3->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID_1;
|
||||
ie3->value.choice.GNB_DU_UE_F1AP_ID_1 = *msg->old_gNB_DU_ue_id;
|
||||
}
|
||||
// SRB ID (M)
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie4);
|
||||
ie4->id = F1AP_ProtocolIE_ID_id_SRBID;
|
||||
ie4->criticality = F1AP_Criticality_reject;
|
||||
ie4->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_SRBID;
|
||||
ie4->value.choice.SRBID = msg->srb_id;
|
||||
// Execute Duplication (O)
|
||||
if (msg->execute_duplication) {
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie5);
|
||||
ie5->id = F1AP_ProtocolIE_ID_id_ExecuteDuplication;
|
||||
ie5->criticality = F1AP_Criticality_ignore;
|
||||
ie5->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_ExecuteDuplication;
|
||||
ie5->value.choice.ExecuteDuplication = F1AP_ExecuteDuplication_true;
|
||||
}
|
||||
// RRC-Container (M)
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie6);
|
||||
ie6->id = F1AP_ProtocolIE_ID_id_RRCContainer;
|
||||
ie6->criticality = F1AP_Criticality_reject;
|
||||
ie6->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_RRCContainer;
|
||||
OCTET_STRING_fromBuf(&ie6->value.choice.RRCContainer, (const char *)msg->rrc_container, msg->rrc_container_length);
|
||||
|
||||
return pdu;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DL RRC Message Transfer decoding (9.2.3.2 of 3GPP TS 38.473)
|
||||
* gNB-CU → gNB-DU
|
||||
*/
|
||||
bool decode_dl_rrc_message_transfer(const F1AP_F1AP_PDU_t *pdu, f1ap_dl_rrc_message_t *out)
|
||||
{
|
||||
DevAssert(out != NULL);
|
||||
memset(out, 0, sizeof(*out));
|
||||
|
||||
DevAssert(pdu != NULL);
|
||||
F1AP_DLRRCMessageTransfer_t *container = &pdu->choice.initiatingMessage->value.choice.DLRRCMessageTransfer;
|
||||
F1AP_DLRRCMessageTransferIEs_t *ie;
|
||||
// gNB-CU UE F1AP ID (M)
|
||||
F1AP_LIB_FIND_IE(F1AP_DLRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
|
||||
out->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
|
||||
// gNB-DU UE F1AP ID (M)
|
||||
F1AP_LIB_FIND_IE(F1AP_DLRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
|
||||
out->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
|
||||
// old gNB-DU UE F1AP ID (O)
|
||||
out->old_gNB_DU_ue_id = NULL;
|
||||
F1AP_LIB_FIND_IE(F1AP_DLRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID, false);
|
||||
if (ie) {
|
||||
out->old_gNB_DU_ue_id = malloc_or_fail(sizeof(*out->old_gNB_DU_ue_id));
|
||||
*out->old_gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID_1;
|
||||
}
|
||||
// SRB ID (M)
|
||||
F1AP_LIB_FIND_IE(F1AP_DLRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_SRBID, true);
|
||||
out->srb_id = ie->value.choice.SRBID;
|
||||
// Execute Duplication (O)
|
||||
F1AP_LIB_FIND_IE(F1AP_DLRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_ExecuteDuplication, false);
|
||||
if (ie) {
|
||||
out->execute_duplication = ie->value.choice.ExecuteDuplication;
|
||||
}
|
||||
// RRC-Container (M)
|
||||
F1AP_LIB_FIND_IE(F1AP_DLRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_RRCContainer, true);
|
||||
out->rrc_container = cp_octet_string(&ie->value.choice.RRCContainer, &out->rrc_container_length);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DL RRC Message Transfer deep copy
|
||||
*/
|
||||
f1ap_dl_rrc_message_t cp_dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *msg)
|
||||
{
|
||||
uint8_t *rrc_container = calloc_or_fail(msg->rrc_container_length, sizeof(*rrc_container));
|
||||
memcpy(rrc_container, msg->rrc_container, msg->rrc_container_length);
|
||||
|
||||
uint32_t *old_gNB_DU_ue_id = NULL;
|
||||
if (msg->old_gNB_DU_ue_id) {
|
||||
old_gNB_DU_ue_id = malloc_or_fail(sizeof(*old_gNB_DU_ue_id));
|
||||
*old_gNB_DU_ue_id = *(msg->old_gNB_DU_ue_id);
|
||||
}
|
||||
|
||||
f1ap_dl_rrc_message_t cp = {
|
||||
.gNB_DU_ue_id = msg->gNB_DU_ue_id,
|
||||
.gNB_CU_ue_id = msg->gNB_CU_ue_id,
|
||||
.old_gNB_DU_ue_id = old_gNB_DU_ue_id,
|
||||
.srb_id = msg->srb_id,
|
||||
.execute_duplication = msg->execute_duplication,
|
||||
.rrc_container = rrc_container,
|
||||
.rrc_container_length = msg->rrc_container_length,
|
||||
};
|
||||
|
||||
return cp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DL RRC Message Transfer equality check
|
||||
*/
|
||||
bool eq_dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *a, const f1ap_dl_rrc_message_t *b)
|
||||
{
|
||||
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
|
||||
_F1_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
|
||||
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
|
||||
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
|
||||
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
|
||||
if (!(a->old_gNB_DU_ue_id == NULL && b->old_gNB_DU_ue_id == NULL))
|
||||
_F1_EQ_CHECK_INT(*a->old_gNB_DU_ue_id, *b->old_gNB_DU_ue_id);
|
||||
_F1_EQ_CHECK_INT(a->srb_id, b->srb_id);
|
||||
_F1_EQ_CHECK_INT(a->execute_duplication, b->execute_duplication);
|
||||
_F1_EQ_CHECK_INT(a->rrc_container_length, b->rrc_container_length);
|
||||
if (memcmp(a->rrc_container, b->rrc_container, a->rrc_container_length) != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DL RRC Message Transfer memory management
|
||||
*/
|
||||
void free_dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *msg)
|
||||
{
|
||||
DevAssert(msg != NULL);
|
||||
free(msg->rrc_container);
|
||||
free(msg->old_gNB_DU_ue_id);
|
||||
}
|
||||
|
||||
@@ -33,4 +33,11 @@ f1ap_initial_ul_rrc_message_t cp_initial_ul_rrc_message_transfer(const f1ap_init
|
||||
bool eq_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *a, const f1ap_initial_ul_rrc_message_t *b);
|
||||
void free_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *msg);
|
||||
|
||||
/* DL RRC Message transfer */
|
||||
struct F1AP_F1AP_PDU *encode_dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *msg);
|
||||
bool decode_dl_rrc_message_transfer(const struct F1AP_F1AP_PDU *pdu, f1ap_dl_rrc_message_t *out);
|
||||
f1ap_dl_rrc_message_t cp_dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *msg);
|
||||
bool eq_dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *a, const f1ap_dl_rrc_message_t *b);
|
||||
void free_dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *msg);
|
||||
|
||||
#endif /* F1AP_RRC_MESSAGE_TRANSFER_H_ */
|
||||
|
||||
Reference in New Issue
Block a user