diff --git a/openair2/F1AP/lib/f1ap_rrc_message_transfer.c b/openair2/F1AP/lib/f1ap_rrc_message_transfer.c index e449d68096..5fc9e2d622 100644 --- a/openair2/F1AP/lib/f1ap_rrc_message_transfer.c +++ b/openair2/F1AP/lib/f1ap_rrc_message_transfer.c @@ -23,7 +23,6 @@ #include "f1ap_lib_common.h" #include "f1ap_lib_includes.h" - #include "f1ap_messages_types.h" #include "common/utils/assertions.h" @@ -198,6 +197,125 @@ void free_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *m free(msg->du2cu_rrc_container); } +/* ==================================== + * F1AP UL RRC Message Transfer + * ==================================== */ + +/** + * @brief UL RRC Message Transfer encoding (9.2.3.3 of 3GPP TS 38.473) + * gNB-DU → gNB-CU + */ +F1AP_F1AP_PDU_t *encode_ul_rrc_message_transfer(const f1ap_ul_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_ULRRCMessageTransfer; + tmp->criticality = F1AP_Criticality_ignore; + tmp->value.present = F1AP_InitiatingMessage__value_PR_ULRRCMessageTransfer; + F1AP_ULRRCMessageTransfer_t *out = &tmp->value.choice.ULRRCMessageTransfer; + // gNB-CU UE F1AP ID (M) + asn1cSequenceAdd(out->protocolIEs.list, F1AP_ULRRCMessageTransferIEs_t, ie1); + ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; + ie1->criticality = F1AP_Criticality_reject; + ie1->value.present = F1AP_ULRRCMessageTransferIEs__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_ULRRCMessageTransferIEs_t, ie2); + ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; + ie2->criticality = F1AP_Criticality_reject; + ie2->value.present = F1AP_ULRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID; + ie2->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id; + // SRB ID (M) + asn1cSequenceAdd(out->protocolIEs.list, F1AP_ULRRCMessageTransferIEs_t, ie3); + ie3->id = F1AP_ProtocolIE_ID_id_SRBID; + ie3->criticality = F1AP_Criticality_reject; + ie3->value.present = F1AP_ULRRCMessageTransferIEs__value_PR_SRBID; + ie3->value.choice.SRBID = msg->srb_id; + // RRC-Container (M) + asn1cSequenceAdd(out->protocolIEs.list, F1AP_ULRRCMessageTransferIEs_t, ie4); + ie4->id = F1AP_ProtocolIE_ID_id_RRCContainer; + ie4->criticality = F1AP_Criticality_reject; + ie4->value.present = F1AP_ULRRCMessageTransferIEs__value_PR_RRCContainer; + OCTET_STRING_fromBuf(&ie4->value.choice.RRCContainer, (const char *)msg->rrc_container, msg->rrc_container_length); + + return pdu; +} + +/** + * @brief UL RRC Message Transfer decoding (9.2.3.3 of 3GPP TS 38.473) + * gNB-DU → gNB-CU + */ +bool decode_ul_rrc_message_transfer(const F1AP_F1AP_PDU_t *pdu, f1ap_ul_rrc_message_t *out) +{ + DevAssert(out != NULL); + memset(out, 0, sizeof(*out)); + DevAssert(pdu != NULL); + + F1AP_ULRRCMessageTransfer_t *container = &pdu->choice.initiatingMessage->value.choice.ULRRCMessageTransfer; + F1AP_ULRRCMessageTransferIEs_t *ie; + + // gNB-CU UE F1AP ID (M) + F1AP_LIB_FIND_IE(F1AP_ULRRCMessageTransferIEs_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_ULRRCMessageTransferIEs_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; + // SRB ID (M) + F1AP_LIB_FIND_IE(F1AP_ULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_SRBID, true); + out->srb_id = ie->value.choice.SRBID; + // RRC-Container (M) + F1AP_LIB_FIND_IE(F1AP_ULRRCMessageTransferIEs_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 UL RRC Message Transfer deep copy + */ +f1ap_ul_rrc_message_t cp_ul_rrc_message_transfer(const f1ap_ul_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); + f1ap_ul_rrc_message_t cp = { + .gNB_DU_ue_id = msg->gNB_DU_ue_id, + .gNB_CU_ue_id = msg->gNB_CU_ue_id, + .srb_id = msg->srb_id, + .rrc_container = rrc_container, + .rrc_container_length = msg->rrc_container_length, + }; + return cp; +} + +/** + * @brief UL RRC Message Transfer equality check + */ +bool eq_ul_rrc_message_transfer(const f1ap_ul_rrc_message_t *a, const f1ap_ul_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->rrc_container_length, b->rrc_container_length); + _F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id); + if (memcmp(a->rrc_container, b->rrc_container, a->rrc_container_length) != 0) + return false; + return true; +} + +/** + * @brief UL RRC Message Transfer memory management + */ +void free_ul_rrc_message_transfer(const f1ap_ul_rrc_message_t *msg) +{ + DevAssert(msg != NULL); + free(msg->rrc_container); +} + /* ============================ * F1AP DL RRC Message Transfer * ============================ */ diff --git a/openair2/F1AP/lib/f1ap_rrc_message_transfer.h b/openair2/F1AP/lib/f1ap_rrc_message_transfer.h index 60aae835ab..4e6d682f78 100644 --- a/openair2/F1AP/lib/f1ap_rrc_message_transfer.h +++ b/openair2/F1AP/lib/f1ap_rrc_message_transfer.h @@ -40,4 +40,11 @@ f1ap_dl_rrc_message_t cp_dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *ms 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); +/* UL RRC Message transfer */ +struct F1AP_F1AP_PDU *encode_ul_rrc_message_transfer(const f1ap_ul_rrc_message_t *msg); +bool decode_ul_rrc_message_transfer(const struct F1AP_F1AP_PDU *pdu, f1ap_ul_rrc_message_t *out); +f1ap_ul_rrc_message_t cp_ul_rrc_message_transfer(const f1ap_ul_rrc_message_t *msg); +bool eq_ul_rrc_message_transfer(const f1ap_ul_rrc_message_t *a, const f1ap_ul_rrc_message_t *b); +void free_ul_rrc_message_transfer(const f1ap_ul_rrc_message_t *msg); + #endif /* F1AP_RRC_MESSAGE_TRANSFER_H_ */