Merge remote-tracking branch 'origin/f1ap-msg-encdec-tests' into integration_2024_w40b
This commit is contained in:
@@ -163,7 +163,7 @@ typedef struct qos_characteristics_s {
|
||||
} packet_error_rate;
|
||||
} dynamic;
|
||||
};
|
||||
fiveQI_type_t qos_type;
|
||||
fiveQI_t qos_type;
|
||||
} qos_characteristics_t;
|
||||
|
||||
typedef struct ngran_allocation_retention_priority_s {
|
||||
|
||||
@@ -24,8 +24,7 @@
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/sctp.h>
|
||||
#include "s1ap_messages_types.h"
|
||||
#include "ngap_messages_types.h"
|
||||
#include "common/5g_platform_types.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------//
|
||||
// Defines to access message fields.
|
||||
@@ -82,12 +81,12 @@
|
||||
#define F1AP_MAX_NO_UE_ID 1024
|
||||
|
||||
#define F1AP_MAX_NO_OF_INDIVIDUAL_CONNECTIONS_TO_RESET 65536
|
||||
|
||||
typedef net_ip_address_t f1ap_net_ip_address_t;
|
||||
/* 9.3.1.42 of 3GPP TS 38.473 - gNB-CU System Information */
|
||||
#define F1AP_MAX_NO_SIB_TYPES 32
|
||||
|
||||
typedef struct f1ap_net_config_t {
|
||||
f1ap_net_ip_address_t CU_f1_ip_address;
|
||||
f1ap_net_ip_address_t DU_f1c_ip_address;
|
||||
char *CU_f1_ip_address;
|
||||
char *DU_f1c_ip_address;
|
||||
char *DU_f1u_ip_address;
|
||||
uint16_t CUport;
|
||||
uint16_t DUport;
|
||||
@@ -99,6 +98,11 @@ typedef struct f1ap_plmn_t {
|
||||
uint8_t mnc_digit_length;
|
||||
} f1ap_plmn_t;
|
||||
|
||||
typedef struct f1ap_cp_tnl_s {
|
||||
in_addr_t tl_address; // currently only IPv4 supported
|
||||
uint16_t port;
|
||||
} f1ap_cp_tnl_t;
|
||||
|
||||
typedef enum f1ap_mode_t { F1AP_MODE_TDD = 0, F1AP_MODE_FDD = 1 } f1ap_mode_t;
|
||||
|
||||
typedef struct f1ap_nr_frequency_info_t {
|
||||
@@ -179,18 +183,24 @@ typedef struct f1ap_du_register_req_t {
|
||||
f1ap_net_config_t net_config;
|
||||
} f1ap_du_register_req_t;
|
||||
|
||||
typedef struct f1ap_sib_msg_t {
|
||||
/// RRC container with system information owned by gNB-CU
|
||||
uint8_t *SI_container;
|
||||
int SI_container_length;
|
||||
/// SIB block type, e.g. 2 for sibType2
|
||||
int SI_type;
|
||||
} f1ap_sib_msg_t;
|
||||
|
||||
typedef struct served_cells_to_activate_s {
|
||||
f1ap_plmn_t plmn;
|
||||
// NR Global Cell Id
|
||||
uint64_t nr_cellid;
|
||||
/// NRPCI
|
||||
/// NRPCI [int 0..1007]
|
||||
uint16_t nrpci;
|
||||
/// num SI messages per DU cell
|
||||
uint8_t num_SI;
|
||||
/// SI message containers (up to 21 messages per cell)
|
||||
uint8_t *SI_container[21];
|
||||
int SI_container_length[21];
|
||||
int SI_type[21];
|
||||
/// gNB-CU System Information message (up to 32 messages per cell)
|
||||
f1ap_sib_msg_t SI_msg[F1AP_MAX_NO_SIB_TYPES];
|
||||
} served_cells_to_activate_t;
|
||||
|
||||
typedef struct f1ap_setup_resp_s {
|
||||
@@ -208,18 +218,8 @@ typedef struct f1ap_setup_resp_s {
|
||||
} f1ap_setup_resp_t;
|
||||
|
||||
typedef struct f1ap_gnb_cu_configuration_update_s {
|
||||
/* Connexion id used between SCTP/F1AP */
|
||||
uint16_t cnx_id;
|
||||
|
||||
/* SCTP association id */
|
||||
sctp_assoc_t assoc_id;
|
||||
|
||||
/* Number of SCTP streams used for a mme association */
|
||||
uint16_t sctp_in_streams;
|
||||
uint16_t sctp_out_streams;
|
||||
|
||||
/// string holding gNB_CU_name
|
||||
char *gNB_CU_name;
|
||||
/// Transaction ID
|
||||
uint64_t transaction_id;
|
||||
/// number of DU cells to activate
|
||||
uint16_t num_cells_to_activate; //0< num_cells_to_activate/mod <= 512;
|
||||
served_cells_to_activate_t cells_to_activate[F1AP_MAX_NB_CELLS];
|
||||
@@ -228,26 +228,37 @@ typedef struct f1ap_gnb_cu_configuration_update_s {
|
||||
typedef struct f1ap_setup_failure_s {
|
||||
uint16_t cause;
|
||||
uint16_t time_to_wait;
|
||||
uint16_t criticality_diagnostics;
|
||||
uint16_t criticality_diagnostics;
|
||||
/// Transaction ID (M)
|
||||
uint64_t transaction_id;
|
||||
} f1ap_setup_failure_t;
|
||||
|
||||
typedef struct f1ap_gnb_cu_configuration_update_acknowledge_s {
|
||||
uint64_t transaction_id;
|
||||
// Cells Failed to be Activated List
|
||||
uint16_t num_cells_failed_to_be_activated;
|
||||
f1ap_plmn_t plmn[F1AP_MAX_NB_CELLS];
|
||||
uint64_t nr_cellid[F1AP_MAX_NB_CELLS];
|
||||
uint16_t cause[F1AP_MAX_NB_CELLS];
|
||||
struct {
|
||||
// NR CGI
|
||||
f1ap_plmn_t plmn;
|
||||
uint64_t nr_cellid;
|
||||
uint16_t cause;
|
||||
} cells_failed_to_be_activated[F1AP_MAX_NB_CELLS];
|
||||
int have_criticality;
|
||||
uint16_t criticality_diagnostics;
|
||||
uint16_t criticality_diagnostics;
|
||||
// gNB-CU TNL Association Setup List
|
||||
uint16_t noofTNLAssociations_to_setup;
|
||||
uint16_t have_port[F1AP_MAX_NO_OF_TNL_ASSOCIATIONS];
|
||||
in_addr_t tl_address[F1AP_MAX_NO_OF_TNL_ASSOCIATIONS]; // currently only IPv4 supported
|
||||
f1ap_cp_tnl_t tnlAssociations_to_setup[F1AP_MAX_NO_OF_TNL_ASSOCIATIONS];
|
||||
// gNB-CU TNL Association Failed to Setup List
|
||||
uint16_t noofTNLAssociations_failed;
|
||||
in_addr_t tl_address_failed[F1AP_MAX_NO_OF_TNL_ASSOCIATIONS]; // currently only IPv4 supported
|
||||
uint16_t cause_failed[F1AP_MAX_NO_OF_TNL_ASSOCIATIONS];
|
||||
f1ap_cp_tnl_t tnlAssociations_failed[F1AP_MAX_NO_OF_TNL_ASSOCIATIONS];
|
||||
// Dedicated SI Delivery Needed UE List
|
||||
uint16_t noofDedicatedSIDeliveryNeededUEs;
|
||||
uint32_t gNB_CU_ue_id[F1AP_MAX_NO_UE_ID];
|
||||
f1ap_plmn_t ue_plmn[F1AP_MAX_NO_UE_ID];
|
||||
uint64_t ue_nr_cellid[F1AP_MAX_NO_UE_ID];
|
||||
struct {
|
||||
uint32_t gNB_CU_ue_id;
|
||||
// NR CGI
|
||||
f1ap_plmn_t ue_plmn;
|
||||
uint64_t ue_nr_cellid;
|
||||
} dedicatedSIDeliveryNeededUEs[F1AP_MAX_NO_UE_ID];
|
||||
} f1ap_gnb_cu_configuration_update_acknowledge_t;
|
||||
|
||||
typedef struct f1ap_gnb_cu_configuration_update_failure_s {
|
||||
@@ -285,16 +296,13 @@ typedef struct f1ap_gnb_du_configuration_update_s {
|
||||
f1ap_plmn_t plmn;
|
||||
uint64_t nr_cellid; // NR Global Cell Id
|
||||
} cell_to_delete[F1AP_MAX_NB_CELLS];
|
||||
|
||||
/// string holding gNB_CU_name
|
||||
/// gNB-DU unique ID, at least within a gNB-CU (0 .. 2^36 - 1)
|
||||
uint64_t *gNB_DU_ID;
|
||||
} f1ap_gnb_du_configuration_update_t;
|
||||
|
||||
typedef struct f1ap_gnb_du_configuration_update_acknowledge_s {
|
||||
/// ulong transaction id
|
||||
uint64_t transaction_id;
|
||||
/// string holding gNB_CU_name
|
||||
char *gNB_CU_name;
|
||||
/// number of DU cells to activate
|
||||
uint16_t num_cells_to_activate; // 0< num_cells_to_activate <= 512;
|
||||
served_cells_to_activate_t cells_to_activate[F1AP_MAX_NB_CELLS];
|
||||
@@ -334,6 +342,7 @@ typedef struct f1ap_initial_ul_rrc_message_s {
|
||||
int rrc_container_length;
|
||||
uint8_t *du2cu_rrc_container;
|
||||
int du2cu_rrc_container_length;
|
||||
uint8_t transaction_id;
|
||||
} f1ap_initial_ul_rrc_message_t;
|
||||
|
||||
typedef struct f1ap_ul_rrc_message_s {
|
||||
@@ -346,7 +355,7 @@ typedef struct f1ap_ul_rrc_message_s {
|
||||
|
||||
typedef struct f1ap_up_tnl_s {
|
||||
in_addr_t tl_address; // currently only IPv4 supported
|
||||
teid_t teid;
|
||||
uint32_t teid;
|
||||
uint16_t port;
|
||||
} f1ap_up_tnl_t;
|
||||
|
||||
@@ -376,7 +385,7 @@ typedef struct f1ap_qos_characteristics_s {
|
||||
} packet_error_rate;
|
||||
} dynamic;
|
||||
};
|
||||
fiveQI_type_t qos_type;
|
||||
fiveQI_t qos_type;
|
||||
} f1ap_qos_characteristics_t;
|
||||
|
||||
typedef struct f1ap_ngran_allocation_retention_priority_s {
|
||||
@@ -401,6 +410,7 @@ typedef struct f1ap_drb_information_s {
|
||||
uint8_t flows_to_be_setup_length;
|
||||
} f1ap_drb_information_t;
|
||||
|
||||
typedef enum f1ap_rlc_mode_t { F1AP_RLC_MODE_AM, F1AP_RLC_MODE_UM_BIDIR, F1AP_RLC_UM_UNI_UL, F1AP_RLC_UM_UNI_DL } f1ap_rlc_mode_t;
|
||||
typedef struct f1ap_drb_to_be_setup_s {
|
||||
long drb_id;
|
||||
f1ap_up_tnl_t up_ul_tnl[2];
|
||||
@@ -408,7 +418,7 @@ typedef struct f1ap_drb_to_be_setup_s {
|
||||
f1ap_up_tnl_t up_dl_tnl[2];
|
||||
uint8_t up_dl_tnl_length;
|
||||
f1ap_drb_information_t drb_info;
|
||||
rlc_mode_t rlc_mode;
|
||||
f1ap_rlc_mode_t rlc_mode;
|
||||
nssai_t nssai;
|
||||
} f1ap_drb_to_be_setup_t;
|
||||
|
||||
|
||||
@@ -31,8 +31,9 @@
|
||||
#define NGAP_MESSAGES_TYPES_H_
|
||||
#include "common/platform_constants.h"
|
||||
#include "common/platform_types.h"
|
||||
#include "common/ngran_types.h"
|
||||
#include "common/5g_platform_types.h"
|
||||
#include "LTE_asn_constant.h"
|
||||
#include "s1ap_messages_types.h"
|
||||
//-------------------------------------------------------------------------------------------//
|
||||
// Defines to access message fields.
|
||||
|
||||
@@ -196,16 +197,11 @@ typedef enum ngap_rrc_establishment_cause_e {
|
||||
NGAP_RRC_CAUSE_LAST
|
||||
} ngap_rrc_establishment_cause_t;
|
||||
|
||||
typedef struct nssai_s {
|
||||
uint8_t sst;
|
||||
uint32_t sd;
|
||||
} nssai_t;
|
||||
|
||||
typedef struct pdusession_level_qos_parameter_s {
|
||||
uint8_t qfi;
|
||||
uint64_t fiveQI;
|
||||
uint64_t qos_priority;
|
||||
fiveQI_type_t fiveQI_type;
|
||||
fiveQI_t fiveQI_type;
|
||||
ngap_allocation_retention_priority_t allocation_retention_priority;
|
||||
} pdusession_level_qos_parameter_t;
|
||||
|
||||
|
||||
@@ -686,7 +686,7 @@ static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_bearer_setup_req_t *const bear
|
||||
ieC6_1_1_1->qoS_Flow_Identifier = k->qfi;
|
||||
/* QoS Characteristics */
|
||||
qos_characteristics_t *qos_char_in = &k->qos_params.qos_characteristics;
|
||||
if (qos_char_in->qos_type == non_dynamic) { // non Dynamic 5QI
|
||||
if (qos_char_in->qos_type == NON_DYNAMIC) { // non Dynamic 5QI
|
||||
ieC6_1_1_1->qoSFlowLevelQoSParameters.qoS_Characteristics.present = E1AP_QoS_Characteristics_PR_non_Dynamic_5QI;
|
||||
asn1cCalloc(ieC6_1_1_1->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI, non_Dynamic_5QI);
|
||||
non_Dynamic_5QI->fiveQI = qos_char_in->non_dynamic.fiveqi;
|
||||
@@ -1002,12 +1002,12 @@ static void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, e1a
|
||||
|
||||
qos_characteristics_t *qos_char = &qos_flow->qos_params.qos_characteristics;
|
||||
if (qos2Setup->qoSFlowLevelQoSParameters.qoS_Characteristics.present == E1AP_QoS_Characteristics_PR_non_Dynamic_5QI) {
|
||||
qos_char->qos_type = non_dynamic;
|
||||
qos_char->qos_type = NON_DYNAMIC;
|
||||
qos_char->non_dynamic.fiveqi =
|
||||
qos2Setup->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI->fiveQI;
|
||||
} else {
|
||||
E1AP_Dynamic5QIDescriptor_t *dynamic5QI = qos2Setup->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI;
|
||||
qos_char->qos_type = dynamic;
|
||||
qos_char->qos_type = DYNAMIC;
|
||||
qos_char->dynamic.qos_priority_level = dynamic5QI->qoSPriorityLevel;
|
||||
qos_char->dynamic.packet_delay_budget = dynamic5QI->packetDelayBudget;
|
||||
qos_char->dynamic.packet_error_rate.per_scalar = dynamic5QI->packetErrorRate.pER_Scalar;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
add_subdirectory(lib)
|
||||
add_subdirectory(MESSAGES)
|
||||
|
||||
if(ENABLE_TESTS)
|
||||
@@ -5,4 +6,6 @@ if(ENABLE_TESTS)
|
||||
target_link_libraries(f1ap_ids_test UTIL HASHTABLE minimal_lib)
|
||||
add_dependencies(tests f1ap_ids_test)
|
||||
add_test(NAME F1AP_ID_test COMMAND f1ap_ids_test)
|
||||
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
@@ -411,8 +411,6 @@ typedef struct f1ap_cudu_inst_s {
|
||||
instance_t gtpInst;
|
||||
} f1ap_cudu_inst_t;
|
||||
|
||||
static const int nrb_lut[29] = {11, 18, 24, 25, 31, 32, 38, 51, 52, 65, 66, 78, 79, 93, 106, 107, 121, 132, 133, 135, 160, 162, 189, 216, 217, 245, 264, 270, 273};
|
||||
|
||||
uint8_t F1AP_get_next_transaction_identifier(instance_t mod_idP, instance_t cu_mod_idP);
|
||||
|
||||
f1ap_cudu_inst_t *getCxt(instance_t instanceP);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -36,17 +36,9 @@
|
||||
/*
|
||||
* Reset
|
||||
*/
|
||||
int CU_send_RESET(sctp_assoc_t assoc_id, const f1ap_reset_t *reset);
|
||||
int CU_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
||||
int CU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
||||
int CU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack);
|
||||
|
||||
/*
|
||||
* Error Indication
|
||||
*/
|
||||
int CU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
||||
int CU_send_ERROR_INDICATION(sctp_assoc_t assoc_id, F1AP_ErrorIndication_t *ErrorIndication);
|
||||
|
||||
/*
|
||||
* F1 Setup
|
||||
*/
|
||||
@@ -61,9 +53,6 @@ int CU_send_F1_SETUP_FAILURE(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *
|
||||
*/
|
||||
int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
int CU_send_gNB_DU_CONFIGURATION_FAILURE(sctp_assoc_t assoc_id,
|
||||
f1ap_gnb_du_configuration_update_failure_t *GNBDUConfigurationUpdateFailure);
|
||||
|
||||
int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(
|
||||
sctp_assoc_t assoc_id,
|
||||
f1ap_gnb_du_configuration_update_acknowledge_t *GNBDUConfigurationUpdateAcknowledge);
|
||||
@@ -72,25 +61,10 @@ int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(
|
||||
* gNB-CU Configuration Update
|
||||
*/
|
||||
int CU_send_gNB_CU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_gnb_cu_configuration_update_t *f1ap_gnb_cu_configuration_update);
|
||||
int CU_handle_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
|
||||
sctp_assoc_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
int CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
|
||||
sctp_assoc_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
/*
|
||||
* gNB-DU Resource Coordination
|
||||
*/
|
||||
int CU_handle_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance,
|
||||
sctp_assoc_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
int CU_send_gNB_DU_RESOURCE_COORDINATION_RESPONSE(sctp_assoc_t assoc_id,
|
||||
F1AP_GNBDUResourceCoordinationResponse_t *GNBDUResourceCoordinationResponse);
|
||||
|
||||
#endif /* F1AP_CU_INTERFACE_MANAGEMENT_H_ */
|
||||
|
||||
@@ -39,67 +39,25 @@
|
||||
#include "openair3/UTILS/conversions.h"
|
||||
#include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
|
||||
|
||||
#include "f1ap_rrc_message_transfer.h"
|
||||
|
||||
/*
|
||||
Initial UL RRC Message Transfer
|
||||
*/
|
||||
|
||||
int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
||||
{
|
||||
LOG_D(F1AP, "CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER\n");
|
||||
// decode the F1 message
|
||||
// get the rrc message from the contauiner
|
||||
// call func rrc_eNB_decode_ccch: <-- needs some update here
|
||||
MessageDef *message_p;
|
||||
F1AP_InitialULRRCMessageTransfer_t *container;
|
||||
F1AP_InitialULRRCMessageTransferIEs_t *ie;
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
if (stream != 0) {
|
||||
LOG_E(F1AP, "[SCTP %d] Received F1 on stream != 0 (%d)\n",
|
||||
assoc_id, stream);
|
||||
f1ap_initial_ul_rrc_message_t msg;
|
||||
if (!decode_initial_ul_rrc_message_transfer(pdu, &msg)) {
|
||||
LOG_E(F1AP, "cannot decode F1 initial UL RRC message Transfer\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
container = &pdu->choice.initiatingMessage->value.choice.InitialULRRCMessageTransfer;
|
||||
/* GNB_DU_UE_F1AP_ID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
|
||||
uint32_t du_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
|
||||
|
||||
/* NRCGI
|
||||
* Fixme: process NRCGI
|
||||
*/
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_NRCGI, true);
|
||||
uint64_t nr_cellid;
|
||||
BIT_STRING_TO_NR_CELL_IDENTITY(&ie->value.choice.NRCGI.nRCellIdentity,nr_cellid);
|
||||
/* RNTI */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_C_RNTI, true);
|
||||
rnti_t rnti = ie->value.choice.C_RNTI;
|
||||
F1AP_InitialULRRCMessageTransferIEs_t *rrccont;
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, rrccont, container,
|
||||
F1AP_ProtocolIE_ID_id_RRCContainer, true);
|
||||
AssertFatal(rrccont!=NULL,"RRCContainer is missing\n");
|
||||
|
||||
F1AP_InitialULRRCMessageTransferIEs_t *du2cu;
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, du2cu, container,
|
||||
F1AP_ProtocolIE_ID_id_DUtoCURRCContainer, false);
|
||||
|
||||
// create an ITTI message and copy SDU
|
||||
message_p = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_INITIAL_UL_RRC_MESSAGE);
|
||||
MessageDef *message_p = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_INITIAL_UL_RRC_MESSAGE);
|
||||
message_p->ittiMsgHeader.originInstance = assoc_id;
|
||||
f1ap_initial_ul_rrc_message_t *ul_rrc = &F1AP_INITIAL_UL_RRC_MESSAGE(message_p);
|
||||
ul_rrc->gNB_DU_ue_id = du_ue_id;
|
||||
ul_rrc->nr_cellid = nr_cellid; // CU instance
|
||||
ul_rrc->crnti = rnti;
|
||||
ul_rrc->rrc_container_length = rrccont->value.choice.RRCContainer.size;
|
||||
ul_rrc->rrc_container = malloc(ul_rrc->rrc_container_length);
|
||||
memcpy(ul_rrc->rrc_container, rrccont->value.choice.RRCContainer.buf, ul_rrc->rrc_container_length);
|
||||
AssertFatal(du2cu != NULL, "no masterCellGroup in initial UL RRC message\n");
|
||||
ul_rrc->du2cu_rrc_container_length = du2cu->value.choice.DUtoCURRCContainer.size;
|
||||
ul_rrc->du2cu_rrc_container = malloc(ul_rrc->du2cu_rrc_container_length);
|
||||
memcpy(ul_rrc->du2cu_rrc_container, du2cu->value.choice.DUtoCURRCContainer.buf, ul_rrc->du2cu_rrc_container_length);
|
||||
*ul_rrc = msg; /* "move" message into ITTI, RRC thread will free it */
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, instance, message_p);
|
||||
|
||||
return 0;
|
||||
@@ -108,105 +66,27 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t
|
||||
/*
|
||||
DL RRC Message Transfer.
|
||||
*/
|
||||
int CU_send_DL_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, f1ap_dl_rrc_message_t *f1ap_dl_rrc)
|
||||
int CU_send_DL_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, f1ap_dl_rrc_message_t *msg)
|
||||
{
|
||||
LOG_D(F1AP, "CU send DL_RRC_MESSAGE_TRANSFER \n");
|
||||
F1AP_F1AP_PDU_t pdu= {0};
|
||||
F1AP_DLRRCMessageTransfer_t *out;
|
||||
uint8_t *buffer=NULL;
|
||||
uint32_t len=0;
|
||||
/* 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;
|
||||
out = &tmp->value.choice.DLRRCMessageTransfer;
|
||||
/* mandatory */
|
||||
/* c1. GNB_CU_UE_F1AP_ID */
|
||||
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;
|
||||
DevAssert(f1ap_dl_rrc->gNB_CU_ue_id != 0);
|
||||
ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_dl_rrc->gNB_CU_ue_id;
|
||||
|
||||
/* mandatory */
|
||||
/* c2. GNB_DU_UE_F1AP_ID */
|
||||
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;
|
||||
DevAssert(f1ap_dl_rrc->gNB_DU_ue_id != 0);
|
||||
ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_dl_rrc->gNB_DU_ue_id;
|
||||
|
||||
/* optional */
|
||||
/* c3. oldgNB_DU_UE_F1AP_ID */
|
||||
if (f1ap_dl_rrc->old_gNB_DU_ue_id != NULL) {
|
||||
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 = *f1ap_dl_rrc->old_gNB_DU_ue_id;
|
||||
}
|
||||
|
||||
/* mandatory */
|
||||
/* c4. SRBID */
|
||||
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 = f1ap_dl_rrc->srb_id;
|
||||
|
||||
/* optional */
|
||||
/* c5. ExecuteDuplication */
|
||||
if (f1ap_dl_rrc->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;
|
||||
}
|
||||
|
||||
// issue in here
|
||||
/* mandatory */
|
||||
/* c6. RRCContainer */
|
||||
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 *)f1ap_dl_rrc->rrc_container, f1ap_dl_rrc->rrc_container_length);
|
||||
|
||||
/* optional */
|
||||
/* c7. RAT_FrequencyPriorityInformation */
|
||||
/* TODO */
|
||||
if (0) {
|
||||
int endc=1;
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie7);
|
||||
ie7->id = F1AP_ProtocolIE_ID_id_RAT_FrequencyPriorityInformation;
|
||||
ie7->criticality = F1AP_Criticality_reject;
|
||||
ie7->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_RAT_FrequencyPriorityInformation;
|
||||
|
||||
if (endc==1) {
|
||||
ie7->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_eNDC;
|
||||
ie7->value.choice.RAT_FrequencyPriorityInformation.choice.eNDC = 123L;
|
||||
} else {
|
||||
ie7->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_nGRAN;
|
||||
ie7->value.choice.RAT_FrequencyPriorityInformation.choice.nGRAN = 11L;
|
||||
}
|
||||
|
||||
//ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_rAT_FrequencySelectionPriority;
|
||||
//ie->value.choice.RAT_FrequencyPriorityInformation.choice.rAT_FrequencySelectionPriority = 123L;
|
||||
}
|
||||
|
||||
/* encode */
|
||||
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
LOG_E(F1AP, "Failed to encode F1 DL RRC MESSAGE TRANSFER \n");
|
||||
/* encode DL RRC Message Transfer */
|
||||
F1AP_F1AP_PDU_t *pdu = encode_dl_rrc_message_transfer(msg);
|
||||
if (pdu == NULL) {
|
||||
LOG_E(F1AP, "Failed to encode F1 DL RRC MESSAGE TRANSFER: can't send message!\n");
|
||||
ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* encode F1AP PDU */
|
||||
uint8_t *buffer = NULL;
|
||||
uint32_t len = 0;
|
||||
if (f1ap_encode_pdu(pdu, &buffer, &len) < 0) {
|
||||
LOG_E(F1AP, "Failed to encode F1 DL RRC MESSAGE TRANSFER \n");
|
||||
ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu);
|
||||
return -1;
|
||||
}
|
||||
/* Free F1AP PDU */
|
||||
ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu);
|
||||
/* Send to DU */
|
||||
LOG_D(F1AP, "CU send DL_RRC_MESSAGE_TRANSFER \n");
|
||||
f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
|
||||
return 0;
|
||||
}
|
||||
@@ -216,76 +96,67 @@ int CU_send_DL_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, f1ap_dl_rrc_message_t
|
||||
*/
|
||||
int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
||||
{
|
||||
LOG_D(F1AP, "CU_handle_UL_RRC_MESSAGE_TRANSFER \n");
|
||||
F1AP_ULRRCMessageTransfer_t *container;
|
||||
F1AP_ULRRCMessageTransferIEs_t *ie;
|
||||
uint64_t cu_ue_f1ap_id;
|
||||
uint64_t du_ue_f1ap_id;
|
||||
uint64_t srb_id;
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
if (stream != 0) {
|
||||
LOG_E(F1AP, "[SCTP %d] Received F1 on stream != 0 (%d)\n",
|
||||
assoc_id, stream);
|
||||
return -1;
|
||||
}
|
||||
|
||||
container = &pdu->choice.initiatingMessage->value.choice.ULRRCMessageTransfer;
|
||||
/* GNB_CU_UE_F1AP_ID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
|
||||
cu_ue_f1ap_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
|
||||
/* GNB_DU_UE_F1AP_ID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
|
||||
du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
|
||||
f1ap_ul_rrc_message_t msg = {0};
|
||||
|
||||
if (!cu_exists_f1_ue_data(cu_ue_f1ap_id)) {
|
||||
LOG_E(F1AP, "unknown CU UE ID %ld\n", cu_ue_f1ap_id);
|
||||
return 1;
|
||||
LOG_D(F1AP, "CU_handle_UL_RRC_MESSAGE_TRANSFER \n");
|
||||
if (!decode_ul_rrc_message_transfer(pdu, &msg)) {
|
||||
LOG_E(F1AP, "cannot decode F1 UL RRC message Transfer\n");
|
||||
free_ul_rrc_message_transfer(&msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!cu_exists_f1_ue_data(msg.gNB_CU_ue_id)) {
|
||||
LOG_E(F1AP, "unknown CU UE ID %d\n", msg.gNB_CU_ue_id);
|
||||
free_ul_rrc_message_transfer(&msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* the RLC-PDCP does not transport the DU UE ID (yet), so we drop it here.
|
||||
* For the moment, let's hope this won't become relevant; to sleep in peace,
|
||||
* let's put an assert to check that it is the expected DU UE ID. */
|
||||
f1_ue_data_t ue_data = cu_get_f1_ue_data(cu_ue_f1ap_id);
|
||||
if (ue_data.secondary_ue != du_ue_f1ap_id) {
|
||||
LOG_E(F1AP, "unexpected DU UE ID %u received, expected it to be %lu\n", ue_data.secondary_ue, du_ue_f1ap_id);
|
||||
return 1;
|
||||
f1_ue_data_t ue_data = cu_get_f1_ue_data(msg.gNB_CU_ue_id);
|
||||
if (ue_data.secondary_ue != msg.gNB_DU_ue_id) {
|
||||
LOG_E(F1AP, "unexpected DU UE ID %u received, expected it to be %u\n", ue_data.secondary_ue, msg.gNB_DU_ue_id);
|
||||
free_ul_rrc_message_transfer(&msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* mandatory */
|
||||
/* SRBID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_SRBID, true);
|
||||
srb_id = ie->value.choice.SRBID;
|
||||
|
||||
if (srb_id < 1 )
|
||||
LOG_E(F1AP, "Unexpected UL RRC MESSAGE for srb_id %lu \n", srb_id);
|
||||
if (msg.srb_id < 1)
|
||||
LOG_E(F1AP, "Unexpected UL RRC MESSAGE for SRB %d \n", msg.srb_id);
|
||||
else
|
||||
LOG_D(F1AP, "UL RRC MESSAGE for srb_id %lu in DCCH \n", srb_id);
|
||||
LOG_D(F1AP, "UL RRC MESSAGE for SRB %d in DCCH \n", msg.srb_id);
|
||||
|
||||
protocol_ctxt_t ctxt = {
|
||||
.instance = instance,
|
||||
.module_id = instance,
|
||||
.enb_flag = 1,
|
||||
.eNB_index = 0,
|
||||
.rntiMaybeUEid = msg.gNB_CU_ue_id,
|
||||
};
|
||||
|
||||
LOG_D(F1AP,
|
||||
"[UE %lx] calling pdcp_data_ind for SRB %d with size %d (DCCH) \n",
|
||||
ctxt.rntiMaybeUEid,
|
||||
msg.srb_id,
|
||||
msg.rrc_container_length);
|
||||
uint8_t *mb = malloc16(msg.rrc_container_length);
|
||||
memcpy(mb, msg.rrc_container, msg.rrc_container_length);
|
||||
|
||||
// issue in here
|
||||
/* mandatory */
|
||||
/* RRC Container */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_RRCContainer, true);
|
||||
protocol_ctxt_t ctxt={0};
|
||||
ctxt.instance = instance;
|
||||
ctxt.module_id = instance;
|
||||
ctxt.rntiMaybeUEid = cu_ue_f1ap_id;
|
||||
ctxt.enb_flag = 1;
|
||||
ctxt.eNB_index = 0;
|
||||
uint8_t *mb = malloc16(ie->value.choice.RRCContainer.size);
|
||||
memcpy(mb, ie->value.choice.RRCContainer.buf, ie->value.choice.RRCContainer.size);
|
||||
LOG_D(F1AP, "Calling pdcp_data_ind for UE RNTI %lx srb_id %lu with size %ld (DCCH) \n", ctxt.rntiMaybeUEid, srb_id, ie->value.choice.RRCContainer.size);
|
||||
nr_pdcp_data_ind(&ctxt,
|
||||
1, // srb_flag
|
||||
0, // embms_flag
|
||||
srb_id,
|
||||
ie->value.choice.RRCContainer.size,
|
||||
msg.srb_id,
|
||||
msg.rrc_container_length,
|
||||
mb,
|
||||
NULL,
|
||||
NULL);
|
||||
/* Free UL RRC Message Transfer */
|
||||
free_ul_rrc_message_transfer(&msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ static void f1ap_write_drb_qos_param(const f1ap_qos_flow_level_qos_parameters_t
|
||||
int type = drb_qos_in->qos_characteristics.qos_type;
|
||||
|
||||
const f1ap_qos_characteristics_t *drb_qos_char_in = &drb_qos_in->qos_characteristics;
|
||||
if (type == non_dynamic) {
|
||||
if (type == NON_DYNAMIC) {
|
||||
asn1_qosparam->qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI;
|
||||
asn1cCalloc(asn1_qosparam->qoS_Characteristics.choice.non_Dynamic_5QI, tmp);
|
||||
|
||||
@@ -130,7 +130,7 @@ static void f1ap_write_flows_mapped(const f1ap_flows_mapped_to_drb_t *flows_mapp
|
||||
const f1ap_qos_characteristics_t *flow_qos_char_in = &flow_qos_params_in->qos_characteristics;
|
||||
|
||||
int type = flow_qos_params_in->qos_characteristics.qos_type;
|
||||
if (type == non_dynamic) {
|
||||
if (type == NON_DYNAMIC) {
|
||||
QosParams->present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI;
|
||||
asn1cCalloc(QosParams->choice.non_Dynamic_5QI, tmp);
|
||||
|
||||
@@ -483,12 +483,15 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu
|
||||
/* 12.1.4 rLCMode */
|
||||
/* TODO use rlc_mode from f1ap_drb_to_be_setup */
|
||||
switch (f1ap_ue_context_setup_req->drbs_to_be_setup[i].rlc_mode) {
|
||||
case RLC_MODE_AM:
|
||||
case F1AP_RLC_MODE_AM:
|
||||
drbs_toBeSetup_item->rLCMode = F1AP_RLCMode_rlc_am;
|
||||
break;
|
||||
|
||||
default:
|
||||
case F1AP_RLC_MODE_UM_BIDIR:
|
||||
drbs_toBeSetup_item->rLCMode = F1AP_RLCMode_rlc_um_bidirectional;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(false, "modes other than AM/UM-Bidir not supported\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* OPTIONAL */
|
||||
@@ -1218,12 +1221,15 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte
|
||||
/* 12.1.4 rLCMode */
|
||||
/* TODO use rlc_mode from f1ap_drb_to_be_setup */
|
||||
switch (f1ap_ue_context_modification_req->drbs_to_be_setup[i].rlc_mode) {
|
||||
case RLC_MODE_AM:
|
||||
case F1AP_RLC_MODE_AM:
|
||||
drbs_toBeSetupMod_item->rLCMode = F1AP_RLCMode_rlc_am;
|
||||
break;
|
||||
|
||||
default:
|
||||
case F1AP_RLC_MODE_UM_BIDIR:
|
||||
drbs_toBeSetupMod_item->rLCMode = F1AP_RLCMode_rlc_um_bidirectional;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(false, "modes other than AM/UM-Bidir not supported\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* OPTIONAL */
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file f1ap_du_interface_management.h
|
||||
* \brief f1ap interface management for DU
|
||||
* \author EURECOM/NTUST
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
@@ -34,22 +34,13 @@
|
||||
#include "f1ap_encoder.h"
|
||||
#include "f1ap_itti_messaging.h"
|
||||
#include "f1ap_du_interface_management.h"
|
||||
#include "lib/f1ap_interface_management.h"
|
||||
#include "lib/f1ap_lib_common.h"
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h"
|
||||
#include "assertions.h"
|
||||
|
||||
#include "GNB_APP/gnb_paramdef.h"
|
||||
|
||||
int to_NRNRB(int nrb) {
|
||||
for (int i=0; i<sizeofArray(nrb_lut); i++)
|
||||
if (nrb_lut[i] == nrb)
|
||||
return i;
|
||||
|
||||
if(!RC.nrrrc)
|
||||
return 0;
|
||||
|
||||
AssertFatal(1==0,"nrb %d is not in the list of possible NRNRB\n",nrb);
|
||||
}
|
||||
|
||||
int DU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
||||
{
|
||||
LOG_D(F1AP, "DU_handle_RESET\n");\
|
||||
@@ -160,271 +151,25 @@ int DU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DU_send_RESET(sctp_assoc_t assoc_id, const f1ap_reset_t *reset)
|
||||
{
|
||||
AssertFatal(1==0,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int DU_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
||||
{
|
||||
AssertFatal(1==0,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
/*
|
||||
Error Indication
|
||||
*/
|
||||
|
||||
int DU_send_ERROR_INDICATION(sctp_assoc_t assoc_id, F1AP_F1AP_PDU_t *pdu_p)
|
||||
{
|
||||
AssertFatal(1==0,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int DU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
||||
{
|
||||
AssertFatal(1==0,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
static F1AP_Served_Cell_Information_t encode_served_cell_info(const f1ap_served_cell_info_t *c)
|
||||
{
|
||||
/* 4.1.1 served cell Information */
|
||||
F1AP_Served_Cell_Information_t scell_info = {0};
|
||||
addnRCGI(scell_info.nRCGI, c);
|
||||
|
||||
/* - nRPCI */
|
||||
scell_info.nRPCI = c->nr_pci; // int 0..1007
|
||||
|
||||
/* - fiveGS_TAC */
|
||||
if (c->tac != NULL) {
|
||||
uint32_t tac = htonl(*c->tac);
|
||||
asn1cCalloc(scell_info.fiveGS_TAC, netOrder);
|
||||
OCTET_STRING_fromBuf(netOrder, ((char *)&tac) + 1, 3);
|
||||
}
|
||||
|
||||
/* - Configured_EPS_TAC */
|
||||
if (0) {
|
||||
scell_info.configured_EPS_TAC = (F1AP_Configured_EPS_TAC_t *)calloc(1, sizeof(F1AP_Configured_EPS_TAC_t));
|
||||
OCTET_STRING_fromBuf(scell_info.configured_EPS_TAC, "2", 2);
|
||||
}
|
||||
|
||||
/* servedPLMN information */
|
||||
asn1cSequenceAdd(scell_info.servedPLMNs.list, F1AP_ServedPLMNs_Item_t, servedPLMN_item);
|
||||
MCC_MNC_TO_PLMNID(c->plmn.mcc, c->plmn.mnc, c->plmn.mnc_digit_length, &servedPLMN_item->pLMN_Identity);
|
||||
|
||||
F1AP_NR_Mode_Info_t *nR_Mode_Info = &scell_info.nR_Mode_Info;
|
||||
if (c->num_ssi > 0) {
|
||||
F1AP_ProtocolExtensionContainer_10696P34_t *p = calloc(1, sizeof(*p));
|
||||
servedPLMN_item->iE_Extensions = (struct F1AP_ProtocolExtensionContainer *)p;
|
||||
asn1cSequenceAdd(p->list, F1AP_ServedPLMNs_ItemExtIEs_t, served_plmns_itemExtIEs);
|
||||
served_plmns_itemExtIEs->criticality = F1AP_Criticality_ignore;
|
||||
served_plmns_itemExtIEs->id = F1AP_ProtocolIE_ID_id_TAISliceSupportList;
|
||||
served_plmns_itemExtIEs->extensionValue.present = F1AP_ServedPLMNs_ItemExtIEs__extensionValue_PR_SliceSupportList;
|
||||
F1AP_SliceSupportList_t *slice_support_list = &served_plmns_itemExtIEs->extensionValue.choice.SliceSupportList;
|
||||
|
||||
for (int s = 0; s < c->num_ssi; s++) {
|
||||
asn1cSequenceAdd(slice_support_list->list, F1AP_SliceSupportItem_t, slice);
|
||||
const nssai_t *nssai = &c->nssai[s];
|
||||
INT8_TO_OCTET_STRING(nssai->sst, &slice->sNSSAI.sST);
|
||||
if (nssai->sd != 0xffffff) {
|
||||
asn1cCalloc(slice->sNSSAI.sD, tmp);
|
||||
INT24_TO_OCTET_STRING(nssai->sd, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (c->mode == F1AP_MODE_FDD) { // FDD
|
||||
const f1ap_fdd_info_t *fdd = &c->fdd;
|
||||
nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_fDD;
|
||||
asn1cCalloc(nR_Mode_Info->choice.fDD, fDD_Info);
|
||||
/* FDD.1.1 UL NRFreqInfo ARFCN */
|
||||
fDD_Info->uL_NRFreqInfo.nRARFCN = fdd->ul_freqinfo.arfcn; // Integer
|
||||
|
||||
/* FDD.1.2 F1AP_SUL_Information */
|
||||
|
||||
/* FDD.1.3 freqBandListNr */
|
||||
int ul_band = 1;
|
||||
for (int j = 0; j < ul_band; j++) {
|
||||
asn1cSequenceAdd(fDD_Info->uL_NRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem);
|
||||
/* FDD.1.3.1 freqBandIndicatorNr*/
|
||||
nr_freqBandNrItem->freqBandIndicatorNr = fdd->ul_freqinfo.band;
|
||||
|
||||
/* FDD.1.3.2 supportedSULBandList*/
|
||||
}
|
||||
|
||||
/* FDD.2.1 DL NRFreqInfo ARFCN */
|
||||
fDD_Info->dL_NRFreqInfo.nRARFCN = fdd->dl_freqinfo.arfcn; // Integer
|
||||
|
||||
/* FDD.2.2 F1AP_SUL_Information */
|
||||
|
||||
/* FDD.2.3 freqBandListNr */
|
||||
int dl_bands = 1;
|
||||
for (int j = 0; j < dl_bands; j++) {
|
||||
asn1cSequenceAdd(fDD_Info->dL_NRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem);
|
||||
/* FDD.2.3.1 freqBandIndicatorNr*/
|
||||
nr_freqBandNrItem->freqBandIndicatorNr = fdd->dl_freqinfo.band;
|
||||
|
||||
/* FDD.2.3.2 supportedSULBandList*/
|
||||
} // for FDD : DL freq_Bands
|
||||
|
||||
/* FDD.3 UL Transmission Bandwidth */
|
||||
fDD_Info->uL_Transmission_Bandwidth.nRSCS = fdd->ul_tbw.scs;
|
||||
fDD_Info->uL_Transmission_Bandwidth.nRNRB = to_NRNRB(fdd->ul_tbw.nrb);
|
||||
/* FDD.4 DL Transmission Bandwidth */
|
||||
fDD_Info->dL_Transmission_Bandwidth.nRSCS = fdd->dl_tbw.scs;
|
||||
fDD_Info->dL_Transmission_Bandwidth.nRNRB = to_NRNRB(fdd->dl_tbw.nrb);
|
||||
} else if (c->mode == F1AP_MODE_TDD) {
|
||||
const f1ap_tdd_info_t *tdd = &c->tdd;
|
||||
nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_tDD;
|
||||
asn1cCalloc(nR_Mode_Info->choice.tDD, tDD_Info);
|
||||
/* TDD.1.1 nRFreqInfo ARFCN */
|
||||
tDD_Info->nRFreqInfo.nRARFCN = tdd->freqinfo.arfcn;
|
||||
|
||||
/* TDD.1.2 F1AP_SUL_Information */
|
||||
|
||||
/* TDD.1.3 freqBandListNr */
|
||||
int bands = 1;
|
||||
for (int j = 0; j < bands; j++) {
|
||||
asn1cSequenceAdd(tDD_Info->nRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem);
|
||||
/* TDD.1.3.1 freqBandIndicatorNr*/
|
||||
nr_freqBandNrItem->freqBandIndicatorNr = tdd->freqinfo.band;
|
||||
/* TDD.1.3.2 supportedSULBandList*/
|
||||
}
|
||||
|
||||
/* TDD.2 transmission_Bandwidth */
|
||||
tDD_Info->transmission_Bandwidth.nRSCS = tdd->tbw.scs;
|
||||
tDD_Info->transmission_Bandwidth.nRNRB = to_NRNRB(tdd->tbw.nrb);
|
||||
} else {
|
||||
AssertFatal(false, "unknown mode %d\n", c->mode);
|
||||
}
|
||||
|
||||
/* - measurementTimingConfiguration */
|
||||
OCTET_STRING_fromBuf(&scell_info.measurementTimingConfiguration,
|
||||
(const char *)c->measurement_timing_config,
|
||||
c->measurement_timing_config_len);
|
||||
|
||||
return scell_info;
|
||||
}
|
||||
|
||||
static F1AP_GNB_DU_System_Information_t *encode_system_info(const f1ap_gnb_du_system_info_t *sys_info)
|
||||
{
|
||||
if (sys_info == NULL)
|
||||
return NULL; /* optional: can be NULL */
|
||||
|
||||
F1AP_GNB_DU_System_Information_t *enc_sys_info = calloc(1, sizeof(*enc_sys_info));
|
||||
AssertFatal(enc_sys_info != NULL, "out of memory\n");
|
||||
|
||||
AssertFatal(sys_info->mib != NULL, "MIB must be present in DU sys info\n");
|
||||
OCTET_STRING_fromBuf(&enc_sys_info->mIB_message, (const char *)sys_info->mib, sys_info->mib_length);
|
||||
|
||||
AssertFatal(sys_info->sib1 != NULL, "SIB1 must be present in DU sys info\n");
|
||||
OCTET_STRING_fromBuf(&enc_sys_info->sIB1_message, (const char *)sys_info->sib1, sys_info->sib1_length);
|
||||
|
||||
return enc_sys_info;
|
||||
}
|
||||
|
||||
// SETUP REQUEST
|
||||
/**
|
||||
* @brief F1AP Setup Request
|
||||
*/
|
||||
int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, const f1ap_setup_req_t *setup_req)
|
||||
{
|
||||
LOG_D(F1AP, "DU_send_F1_SETUP_REQUEST\n");
|
||||
|
||||
F1AP_F1AP_PDU_t pdu= {0};
|
||||
F1AP_F1AP_PDU_t *pdu = encode_f1ap_setup_request(setup_req);
|
||||
uint8_t *buffer;
|
||||
uint32_t len;
|
||||
/* Create */
|
||||
/* 0. pdu Type */
|
||||
pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
|
||||
asn1cCalloc(pdu.choice.initiatingMessage, initMsg);
|
||||
initMsg->procedureCode = F1AP_ProcedureCode_id_F1Setup;
|
||||
initMsg->criticality = F1AP_Criticality_reject;
|
||||
initMsg->value.present = F1AP_InitiatingMessage__value_PR_F1SetupRequest;
|
||||
F1AP_F1SetupRequest_t *f1Setup = &initMsg->value.choice.F1SetupRequest;
|
||||
/* mandatory */
|
||||
/* c1. Transaction ID (integer value) */
|
||||
asn1cSequenceAdd(f1Setup->protocolIEs.list, F1AP_F1SetupRequestIEs_t, ieC1);
|
||||
ieC1->id = F1AP_ProtocolIE_ID_id_TransactionID;
|
||||
ieC1->criticality = F1AP_Criticality_reject;
|
||||
ieC1->value.present = F1AP_F1SetupRequestIEs__value_PR_TransactionID;
|
||||
ieC1->value.choice.TransactionID = F1AP_get_next_transaction_identifier(0, 0);
|
||||
/* mandatory */
|
||||
/* c2. GNB_DU_ID (integer value) */
|
||||
asn1cSequenceAdd(f1Setup->protocolIEs.list, F1AP_F1SetupRequestIEs_t, ieC2);
|
||||
ieC2->id = F1AP_ProtocolIE_ID_id_gNB_DU_ID;
|
||||
ieC2->criticality = F1AP_Criticality_reject;
|
||||
ieC2->value.present = F1AP_F1SetupRequestIEs__value_PR_GNB_DU_ID;
|
||||
asn_int642INTEGER(&ieC2->value.choice.GNB_DU_ID, setup_req->gNB_DU_id);
|
||||
|
||||
/* optional */
|
||||
/* c3. GNB_DU_Name */
|
||||
if (setup_req->gNB_DU_name != NULL) {
|
||||
asn1cSequenceAdd(f1Setup->protocolIEs.list, F1AP_F1SetupRequestIEs_t, ieC3);
|
||||
ieC3->id = F1AP_ProtocolIE_ID_id_gNB_DU_Name;
|
||||
ieC3->criticality = F1AP_Criticality_ignore;
|
||||
ieC3->value.present = F1AP_F1SetupRequestIEs__value_PR_GNB_DU_Name;
|
||||
char *gNB_DU_name=setup_req->gNB_DU_name;
|
||||
OCTET_STRING_fromBuf(&ieC3->value.choice.GNB_DU_Name, gNB_DU_name, strlen(gNB_DU_name));
|
||||
}
|
||||
|
||||
/* mandatory */
|
||||
/* c4. served cells list */
|
||||
asn1cSequenceAdd(f1Setup->protocolIEs.list, F1AP_F1SetupRequestIEs_t, ieCells);
|
||||
ieCells->id = F1AP_ProtocolIE_ID_id_gNB_DU_Served_Cells_List;
|
||||
ieCells->criticality = F1AP_Criticality_reject;
|
||||
ieCells->value.present = F1AP_F1SetupRequestIEs__value_PR_GNB_DU_Served_Cells_List;
|
||||
int num_cells_available = setup_req->num_cells_available;
|
||||
LOG_D(F1AP, "num_cells_available = %d \n", num_cells_available);
|
||||
|
||||
for (int i=0; i<num_cells_available; i++) {
|
||||
/* mandatory */
|
||||
/* 4.1 served cells item */
|
||||
const f1ap_served_cell_info_t *cell = &setup_req->cell[i].info;
|
||||
const f1ap_gnb_du_system_info_t *sys_info = setup_req->cell[i].sys_info;
|
||||
asn1cSequenceAdd(ieCells->value.choice.GNB_DU_Served_Cells_List.list,
|
||||
F1AP_GNB_DU_Served_Cells_ItemIEs_t, duServedCell);
|
||||
duServedCell->id = F1AP_ProtocolIE_ID_id_GNB_DU_Served_Cells_Item;
|
||||
duServedCell->criticality = F1AP_Criticality_reject;
|
||||
duServedCell->value.present = F1AP_GNB_DU_Served_Cells_ItemIEs__value_PR_GNB_DU_Served_Cells_Item;
|
||||
F1AP_GNB_DU_Served_Cells_Item_t *scell_item = &duServedCell->value.choice.GNB_DU_Served_Cells_Item;
|
||||
scell_item->served_Cell_Information = encode_served_cell_info(cell);
|
||||
scell_item->gNB_DU_System_Information = encode_system_info(sys_info);
|
||||
}
|
||||
|
||||
/* mandatory */
|
||||
/* c5. RRC VERSION */
|
||||
asn1cSequenceAdd(f1Setup->protocolIEs.list, F1AP_F1SetupRequestIEs_t, ie2);
|
||||
ie2->id = F1AP_ProtocolIE_ID_id_GNB_DU_RRC_Version;
|
||||
ie2->criticality = F1AP_Criticality_reject;
|
||||
ie2->value.present = F1AP_F1SetupRequestIEs__value_PR_RRC_Version;
|
||||
// RRC Version: "This IE is not used in this release."
|
||||
// we put one bit for each byte in rrc_ver that is != 0
|
||||
uint8_t bits = 0;
|
||||
for (int i = 0; i < 3; ++i)
|
||||
bits |= (setup_req->rrc_ver[i] != 0) << i;
|
||||
BIT_STRING_t *bs = &ie2->value.choice.RRC_Version.latest_RRC_Version;
|
||||
bs->buf = calloc(1, sizeof(char));
|
||||
AssertFatal(bs->buf != NULL, "out of memory\n");
|
||||
bs->buf[0] = bits;
|
||||
bs->size = 1;
|
||||
bs->bits_unused = 5;
|
||||
|
||||
F1AP_ProtocolExtensionContainer_10696P228_t *p = calloc(1, sizeof(F1AP_ProtocolExtensionContainer_10696P228_t));
|
||||
asn1cSequenceAdd(p->list, F1AP_RRC_Version_ExtIEs_t, rrcv_ext);
|
||||
rrcv_ext->id = F1AP_ProtocolIE_ID_id_latest_RRC_Version_Enhanced;
|
||||
rrcv_ext->criticality = F1AP_Criticality_ignore;
|
||||
rrcv_ext->extensionValue.present = F1AP_RRC_Version_ExtIEs__extensionValue_PR_OCTET_STRING_SIZE_3_;
|
||||
OCTET_STRING_t *os = &rrcv_ext->extensionValue.choice.OCTET_STRING_SIZE_3_;
|
||||
os->size = 3;
|
||||
os->buf = malloc(3 * sizeof(*os->buf));
|
||||
AssertFatal(os->buf != NULL, "out of memory\n");
|
||||
for (int i = 0; i < 3; ++i)
|
||||
os->buf[i] = setup_req->rrc_ver[i];
|
||||
ie2->value.choice.RRC_Version.iE_Extensions = (struct F1AP_ProtocolExtensionContainer*)p;
|
||||
|
||||
/* encode */
|
||||
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
if (f1ap_encode_pdu(pdu, &buffer, &len) < 0) {
|
||||
LOG_E(F1AP, "Failed to encode F1 setup request\n");
|
||||
/* free PDU */
|
||||
ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu);
|
||||
/* free PDU */
|
||||
ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu);
|
||||
/* Send to ITTI */
|
||||
f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
|
||||
return 0;
|
||||
}
|
||||
@@ -432,475 +177,94 @@ int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, const f1ap_setup_req_t *setu
|
||||
int DU_handle_F1_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
||||
{
|
||||
LOG_D(F1AP, "DU_handle_F1_SETUP_RESPONSE\n");
|
||||
AssertFatal(pdu->present == F1AP_F1AP_PDU_PR_successfulOutcome,
|
||||
"pdu->present != F1AP_F1AP_PDU_PR_successfulOutcome\n");
|
||||
AssertFatal(pdu->choice.successfulOutcome->procedureCode == F1AP_ProcedureCode_id_F1Setup,
|
||||
"pdu->choice.successfulOutcome->procedureCode != F1AP_ProcedureCode_id_F1Setup\n");
|
||||
AssertFatal(pdu->choice.successfulOutcome->criticality == F1AP_Criticality_reject,
|
||||
"pdu->choice.successfulOutcome->criticality != F1AP_Criticality_reject\n");
|
||||
AssertFatal(pdu->choice.successfulOutcome->value.present == F1AP_SuccessfulOutcome__value_PR_F1SetupResponse,
|
||||
"pdu->choice.successfulOutcome->value.present != F1AP_SuccessfulOutcome__value_PR_F1SetupResponse\n");
|
||||
F1AP_F1SetupResponse_t *in = &pdu->choice.successfulOutcome->value.choice.F1SetupResponse;
|
||||
F1AP_F1SetupResponseIEs_t *ie;
|
||||
int TransactionId = -1;
|
||||
int num_cells_to_activate = 0;
|
||||
/* Decode */
|
||||
f1ap_setup_resp_t resp = {0};
|
||||
|
||||
for (int i=0; i < in->protocolIEs.list.count; i++) {
|
||||
ie = in->protocolIEs.list.array[i];
|
||||
|
||||
switch (ie->id) {
|
||||
case F1AP_ProtocolIE_ID_id_TransactionID:
|
||||
AssertFatal(ie->criticality == F1AP_Criticality_reject,
|
||||
"ie->criticality != F1AP_Criticality_reject\n");
|
||||
AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_TransactionID,
|
||||
"ie->value.present != F1AP_F1SetupResponseIEs__value_PR_TransactionID\n");
|
||||
TransactionId=ie->value.choice.TransactionID;
|
||||
LOG_D(F1AP, "F1AP: F1Setup-Resp: TransactionId %d\n",
|
||||
TransactionId);
|
||||
break;
|
||||
|
||||
case F1AP_ProtocolIE_ID_id_gNB_CU_Name:
|
||||
AssertFatal(ie->criticality == F1AP_Criticality_ignore,
|
||||
"ie->criticality != F1AP_Criticality_ignore\n");
|
||||
AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_GNB_CU_Name,
|
||||
"ie->value.present != F1AP_F1SetupResponseIEs__value_PR_GNB_CU_Name\n");
|
||||
resp.gNB_CU_name = malloc(ie->value.choice.GNB_CU_Name.size+1);
|
||||
memcpy(resp.gNB_CU_name, ie->value.choice.GNB_CU_Name.buf, ie->value.choice.GNB_CU_Name.size);
|
||||
resp.gNB_CU_name[ie->value.choice.GNB_CU_Name.size] = '\0';
|
||||
LOG_D(F1AP, "F1AP: F1Setup-Resp: gNB_CU_name %s\n", resp.gNB_CU_name);
|
||||
break;
|
||||
|
||||
case F1AP_ProtocolIE_ID_id_GNB_CU_RRC_Version:
|
||||
AssertFatal(ie->criticality == F1AP_Criticality_reject,
|
||||
"ie->criticality != F1AP_Criticality_reject\n");
|
||||
AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_RRC_Version,
|
||||
"ie->value.present != F1AP_F1SetupResponseIEs__value_PR_RRC_Version\n");
|
||||
// RRC Version: "This IE is not used in this release."
|
||||
if(ie->value.choice.RRC_Version.iE_Extensions) {
|
||||
F1AP_ProtocolExtensionContainer_10696P228_t *ext =
|
||||
(F1AP_ProtocolExtensionContainer_10696P228_t *)ie->value.choice.RRC_Version.iE_Extensions;
|
||||
if(ext->list.count > 0){
|
||||
F1AP_RRC_Version_ExtIEs_t *rrcext = ext->list.array[0];
|
||||
OCTET_STRING_t *os = &rrcext->extensionValue.choice.OCTET_STRING_SIZE_3_;
|
||||
for (int i = 0; i < 3; i++)
|
||||
resp.rrc_ver[i] = os->buf[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List: {
|
||||
AssertFatal(ie->criticality == F1AP_Criticality_reject,
|
||||
"ie->criticality != F1AP_Criticality_reject\n");
|
||||
AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List,
|
||||
"ie->value.present != F1AP_F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List\n");
|
||||
num_cells_to_activate = ie->value.choice.Cells_to_be_Activated_List.list.count;
|
||||
LOG_D(F1AP, "F1AP: Activating %d cells\n",num_cells_to_activate);
|
||||
|
||||
for (int i=0; i<num_cells_to_activate; i++) {
|
||||
F1AP_Cells_to_be_Activated_List_ItemIEs_t *cells_to_be_activated_list_item_ies = (F1AP_Cells_to_be_Activated_List_ItemIEs_t *) ie->value.choice.Cells_to_be_Activated_List.list.array[i];
|
||||
AssertFatal(cells_to_be_activated_list_item_ies->id == F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item,
|
||||
"cells_to_be_activated_list_item_ies->id != F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item");
|
||||
AssertFatal(cells_to_be_activated_list_item_ies->criticality == F1AP_Criticality_reject,
|
||||
"cells_to_be_activated_list_item_ies->criticality == F1AP_Criticality_reject");
|
||||
AssertFatal(cells_to_be_activated_list_item_ies->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item,
|
||||
"cells_to_be_activated_list_item_ies->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item");
|
||||
F1AP_Cells_to_be_Activated_List_Item_t *cell =
|
||||
&cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item;
|
||||
TBCD_TO_MCC_MNC(&cell->nRCGI.pLMN_Identity,
|
||||
resp.cells_to_activate[i].plmn.mcc,
|
||||
resp.cells_to_activate[i].plmn.mnc,
|
||||
resp.cells_to_activate[i].plmn.mnc_digit_length);
|
||||
LOG_D(F1AP, "nr_cellId : %x %x %x %x %x\n",
|
||||
cell->nRCGI.nRCellIdentity.buf[0],
|
||||
cell->nRCGI.nRCellIdentity.buf[1],
|
||||
cell->nRCGI.nRCellIdentity.buf[2],
|
||||
cell->nRCGI.nRCellIdentity.buf[3],
|
||||
cell->nRCGI.nRCellIdentity.buf[4]);
|
||||
BIT_STRING_TO_NR_CELL_IDENTITY(&cell->nRCGI.nRCellIdentity, resp.cells_to_activate[i].nr_cellid);
|
||||
if (cell->nRPCI != NULL)
|
||||
resp.cells_to_activate[i].nrpci = *cell->nRPCI;
|
||||
F1AP_ProtocolExtensionContainer_10696P112_t *ext = (F1AP_ProtocolExtensionContainer_10696P112_t *)cell->iE_Extensions;
|
||||
|
||||
if (ext==NULL)
|
||||
continue;
|
||||
|
||||
for (int cnt=0; cnt<ext->list.count; cnt++) {
|
||||
F1AP_Cells_to_be_Activated_List_ItemExtIEs_t *cells_to_be_activated_list_itemExtIEs=(F1AP_Cells_to_be_Activated_List_ItemExtIEs_t *)ext->list.array[cnt];
|
||||
|
||||
switch (cells_to_be_activated_list_itemExtIEs->id) {
|
||||
/*
|
||||
case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_NOTHING:
|
||||
case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_GNB_CUSystemInformation,
|
||||
case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_AvailablePLMNList,
|
||||
case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_ExtendedAvailablePLMN_List,
|
||||
case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_IAB_Info_IAB_donor_CU,
|
||||
case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_AvailableSNPN_ID_List
|
||||
*/
|
||||
case F1AP_ProtocolIE_ID_id_gNB_CUSystemInformation: {
|
||||
resp.cells_to_activate[i].nrpci = (cell->nRPCI != NULL) ? *cell->nRPCI : 0;
|
||||
F1AP_GNB_CUSystemInformation_t *gNB_CUSystemInformation = (F1AP_GNB_CUSystemInformation_t *)&cells_to_be_activated_list_itemExtIEs->extensionValue.choice.GNB_CUSystemInformation;
|
||||
resp.cells_to_activate[i].num_SI = gNB_CUSystemInformation->sibtypetobeupdatedlist.list.count;
|
||||
AssertFatal(ext->list.count==1,"At least one SI message should be there, and only 1 for now!\n");
|
||||
LOG_D(F1AP,
|
||||
"F1AP: Cell %d MCC %d MNC %d NRCellid %lx num_si %d\n",
|
||||
i,
|
||||
resp.cells_to_activate[i].plmn.mcc,
|
||||
resp.cells_to_activate[i].plmn.mnc,
|
||||
resp.cells_to_activate[i].nr_cellid,
|
||||
resp.cells_to_activate[i].num_SI);
|
||||
|
||||
for (int si = 0; si < gNB_CUSystemInformation->sibtypetobeupdatedlist.list.count; si++) {
|
||||
F1AP_SibtypetobeupdatedListItem_t *sib_item = gNB_CUSystemInformation->sibtypetobeupdatedlist.list.array[si];
|
||||
size_t size = sib_item->sIBmessage.size;
|
||||
resp.cells_to_activate[i].SI_container_length[si] = size;
|
||||
LOG_D(F1AP, "F1AP: SI_container_length[%d][%ld] %ld bytes\n", i, sib_item->sIBtype, size);
|
||||
resp.cells_to_activate[i].SI_container[si] = malloc(resp.cells_to_activate[i].SI_container_length[si]);
|
||||
memcpy(resp.cells_to_activate[i].SI_container[si], sib_item->sIBmessage.buf, size);
|
||||
resp.cells_to_activate[i].SI_type[si]=sib_item->sIBtype;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case F1AP_ProtocolIE_ID_id_AvailablePLMNList:
|
||||
AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n");
|
||||
break;
|
||||
|
||||
case F1AP_ProtocolIE_ID_id_ExtendedAvailablePLMN_List:
|
||||
AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n");
|
||||
break;
|
||||
|
||||
case F1AP_ProtocolIE_ID_id_IAB_Info_IAB_donor_CU:
|
||||
AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n");
|
||||
break;
|
||||
|
||||
case F1AP_ProtocolIE_ID_id_AvailableSNPN_ID_List:
|
||||
AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(1==0,"F1AP_ProtocolIE_ID_id %d unknown\n",(int)cells_to_be_activated_list_itemExtIEs->id);
|
||||
break;
|
||||
}
|
||||
} // for (cnt=...
|
||||
} // for (cells_to_activate...
|
||||
|
||||
break;
|
||||
} // case F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List
|
||||
|
||||
default:
|
||||
AssertFatal(1==0,"F1AP_ProtocolIE_ID_id %d unknown\n", (int)ie->id);
|
||||
break;
|
||||
} // switch ie
|
||||
} // for IE
|
||||
|
||||
AssertFatal(TransactionId!=-1,"TransactionId was not sent\n");
|
||||
LOG_D(F1AP,"F1AP: num_cells_to_activate %d\n",num_cells_to_activate);
|
||||
resp.num_cells_to_activate = num_cells_to_activate;
|
||||
|
||||
// tmp
|
||||
for (int i=0; i<num_cells_to_activate; i++)
|
||||
AssertFatal(resp.cells_to_activate[i].num_SI == 0, "System Information handling not implemented");
|
||||
|
||||
if (!decode_f1ap_setup_response(pdu, &resp)) {
|
||||
LOG_E(F1AP, "cannot decode F1AP Setup Response\n");
|
||||
free_f1ap_setup_response(&resp);
|
||||
return -1;
|
||||
}
|
||||
LOG_D(F1AP, "Sending F1AP_SETUP_RESP ITTI message\n");
|
||||
f1_setup_response(&resp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// SETUP FAILURE
|
||||
/**
|
||||
* @brief F1 Setup Failure handler (DU)
|
||||
*/
|
||||
int DU_handle_F1_SETUP_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
||||
{
|
||||
F1AP_F1SetupFailure_t *out;
|
||||
F1AP_F1SetupFailureIEs_t *ie;
|
||||
f1ap_setup_failure_t fail = {0};
|
||||
out = &pdu->choice.unsuccessfulOutcome->value.choice.F1SetupFailure;
|
||||
/* Transaction ID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupFailureIEs_t, ie, out, F1AP_ProtocolIE_ID_id_TransactionID, true);
|
||||
/* Cause */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupFailureIEs_t, ie, out,
|
||||
F1AP_ProtocolIE_ID_id_Cause, true);
|
||||
|
||||
if(0) {
|
||||
/* TimeToWait */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupFailureIEs_t, ie, out,
|
||||
F1AP_ProtocolIE_ID_id_TimeToWait, true);
|
||||
f1ap_setup_failure_t fail;
|
||||
if (!decode_f1ap_setup_failure(pdu, &fail)) {
|
||||
LOG_E(F1AP, "Failed to decode F1AP Setup Failure\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
f1_setup_failure(&fail);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
gNB-DU Configuration Update
|
||||
*/
|
||||
|
||||
int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, const f1ap_gnb_du_configuration_update_t *upd)
|
||||
/**
|
||||
* @brief F1 gNB-DU Configuration Update: encoding and ITTI transmission
|
||||
*/
|
||||
int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_gnb_du_configuration_update_t *msg)
|
||||
{
|
||||
F1AP_F1AP_PDU_t pdu= {0};
|
||||
uint8_t *buffer=NULL;
|
||||
uint32_t len=0;
|
||||
/* Create */
|
||||
/* 0. Message Type */
|
||||
pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
|
||||
asn1cCalloc(pdu.choice.initiatingMessage, initMsg);
|
||||
initMsg->procedureCode = F1AP_ProcedureCode_id_gNBDUConfigurationUpdate;
|
||||
initMsg->criticality = F1AP_Criticality_reject;
|
||||
initMsg->value.present = F1AP_InitiatingMessage__value_PR_GNBDUConfigurationUpdate;
|
||||
F1AP_GNBDUConfigurationUpdate_t *out = &initMsg->value.choice.GNBDUConfigurationUpdate;
|
||||
|
||||
/* mandatory */
|
||||
/* c1. Transaction ID (integer value) */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_GNBDUConfigurationUpdateIEs_t, ie1);
|
||||
ie1->id = F1AP_ProtocolIE_ID_id_TransactionID;
|
||||
ie1->criticality = F1AP_Criticality_reject;
|
||||
ie1->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_TransactionID;
|
||||
ie1->value.choice.TransactionID = upd->transaction_id;
|
||||
|
||||
/* mandatory */
|
||||
/* c2. Served_Cells_To_Add */
|
||||
if (upd->num_cells_to_add > 0) {
|
||||
AssertFatal(false, "code for adding cells not tested\n");
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_GNBDUConfigurationUpdateIEs_t, ie2);
|
||||
ie2->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Add_List;
|
||||
ie2->criticality = F1AP_Criticality_reject;
|
||||
ie2->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Add_List;
|
||||
|
||||
for (int j = 0; j < upd->num_cells_to_add; j++) {
|
||||
const f1ap_served_cell_info_t *cell = &upd->cell_to_add[j].info;
|
||||
const f1ap_gnb_du_system_info_t *sys_info = upd->cell_to_add[j].sys_info;
|
||||
asn1cSequenceAdd(ie2->value.choice.Served_Cells_To_Add_List.list,
|
||||
F1AP_Served_Cells_To_Add_ItemIEs_t,
|
||||
served_cells_to_add_item_ies);
|
||||
served_cells_to_add_item_ies->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Add_Item;
|
||||
served_cells_to_add_item_ies->criticality = F1AP_Criticality_reject;
|
||||
served_cells_to_add_item_ies->value.present = F1AP_Served_Cells_To_Add_ItemIEs__value_PR_Served_Cells_To_Add_Item;
|
||||
F1AP_Served_Cells_To_Add_Item_t *served_cells_to_add_item =
|
||||
&served_cells_to_add_item_ies->value.choice.Served_Cells_To_Add_Item;
|
||||
served_cells_to_add_item->served_Cell_Information = encode_served_cell_info(cell);
|
||||
served_cells_to_add_item->gNB_DU_System_Information = encode_system_info(sys_info);
|
||||
}
|
||||
}
|
||||
|
||||
/* mandatory */
|
||||
/* c3. Served_Cells_To_Modify */
|
||||
if (upd->num_cells_to_modify > 0) {
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_GNBDUConfigurationUpdateIEs_t, ie3);
|
||||
ie3->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Modify_List;
|
||||
ie3->criticality = F1AP_Criticality_reject;
|
||||
ie3->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Modify_List;
|
||||
for (int i = 0; i < upd->num_cells_to_modify; i++) {
|
||||
const f1ap_served_cell_info_t *cell = &upd->cell_to_modify[i].info;
|
||||
const f1ap_gnb_du_system_info_t *sys_info = upd->cell_to_modify[i].sys_info;
|
||||
asn1cSequenceAdd(ie3->value.choice.Served_Cells_To_Modify_List.list,
|
||||
F1AP_Served_Cells_To_Modify_ItemIEs_t,
|
||||
served_cells_to_modify_item_ies);
|
||||
served_cells_to_modify_item_ies->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Modify_Item;
|
||||
served_cells_to_modify_item_ies->criticality = F1AP_Criticality_reject;
|
||||
served_cells_to_modify_item_ies->value.present = F1AP_Served_Cells_To_Modify_ItemIEs__value_PR_Served_Cells_To_Modify_Item;
|
||||
F1AP_Served_Cells_To_Modify_Item_t *served_cells_to_modify_item =
|
||||
&served_cells_to_modify_item_ies->value.choice.Served_Cells_To_Modify_Item;
|
||||
|
||||
F1AP_NRCGI_t *oldNRCGI = &served_cells_to_modify_item->oldNRCGI;
|
||||
const f1ap_plmn_t *old_plmn = &upd->cell_to_modify[i].old_plmn;
|
||||
MCC_MNC_TO_PLMNID(old_plmn->mcc, old_plmn->mnc, old_plmn->mnc_digit_length, &oldNRCGI->pLMN_Identity);
|
||||
NR_CELL_ID_TO_BIT_STRING(upd->cell_to_modify[i].old_nr_cellid, &oldNRCGI->nRCellIdentity);
|
||||
|
||||
served_cells_to_modify_item->served_Cell_Information = encode_served_cell_info(cell);
|
||||
served_cells_to_modify_item->gNB_DU_System_Information = encode_system_info(sys_info);
|
||||
}
|
||||
}
|
||||
|
||||
/* mandatory */
|
||||
/* c4. Served_Cells_To_Delete */
|
||||
if (upd->num_cells_to_delete > 0) {
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_GNBDUConfigurationUpdateIEs_t, ie4);
|
||||
ie4->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Delete_List;
|
||||
ie4->criticality = F1AP_Criticality_reject;
|
||||
ie4->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Delete_List;
|
||||
AssertFatal(upd->num_cells_to_delete == 0, "code for deleting cells not tested\n");
|
||||
for (int i = 0; i < upd->num_cells_to_delete; i++) {
|
||||
asn1cSequenceAdd(ie4->value.choice.Served_Cells_To_Delete_List.list,
|
||||
F1AP_Served_Cells_To_Delete_ItemIEs_t,
|
||||
served_cells_to_delete_item_ies);
|
||||
served_cells_to_delete_item_ies->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Delete_Item;
|
||||
served_cells_to_delete_item_ies->criticality = F1AP_Criticality_reject;
|
||||
served_cells_to_delete_item_ies->value.present = F1AP_Served_Cells_To_Delete_ItemIEs__value_PR_Served_Cells_To_Delete_Item;
|
||||
F1AP_Served_Cells_To_Delete_Item_t *served_cells_to_delete_item =
|
||||
&served_cells_to_delete_item_ies->value.choice.Served_Cells_To_Delete_Item;
|
||||
addnRCGI(served_cells_to_delete_item->oldNRCGI, &upd->cell_to_delete[i]);
|
||||
}
|
||||
}
|
||||
|
||||
AssertFatal(upd->gNB_DU_ID == 0, "encoding of gNB-DU Id not handled yet\n");
|
||||
|
||||
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
/* encode F1AP message */
|
||||
F1AP_F1AP_PDU_t *pdu = encode_f1ap_du_configuration_update(msg);
|
||||
/* free anfter encoding */
|
||||
free_f1ap_du_configuration_update(msg);
|
||||
/* encode F1AP pdu */
|
||||
if (f1ap_encode_pdu(pdu, &buffer, &len) < 0) {
|
||||
LOG_E(F1AP, "Failed to encode F1 gNB-DU CONFIGURATION UPDATE\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu);
|
||||
/* transfer the message */
|
||||
ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu);
|
||||
f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DU_handle_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
||||
/**
|
||||
* @brief F1 gNB-CU Configuration Update decoding and message transfer
|
||||
*/
|
||||
int DU_handle_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
||||
{
|
||||
AssertFatal(1==0,"Not implemented yet\n");
|
||||
LOG_D(F1AP, "DU_handle_gNB_CU_CONFIGURATION_UPDATE\n");
|
||||
f1ap_gnb_cu_configuration_update_t in = {0};
|
||||
if (!decode_f1ap_cu_configuration_update(pdu, &in)) {
|
||||
LOG_E(F1AP, "Failed to decode F1AP Setup Failure\n");
|
||||
free_f1ap_cu_configuration_update(&in);
|
||||
return -1;
|
||||
}
|
||||
MessageDef *msg_p = itti_alloc_new_message (TASK_DU_F1, 0, F1AP_GNB_CU_CONFIGURATION_UPDATE);
|
||||
f1ap_gnb_cu_configuration_update_t *msg = &F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p); // RRC thread will free it
|
||||
*msg = in; // copy F1 message to ITTI
|
||||
LOG_D(F1AP, "Sending F1AP_GNB_CU_CONFIGURATION_UPDATE ITTI message \n");
|
||||
itti_send_msg_to_task(TASK_GNB_APP, GNB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief F1 gNB-DU Configuration Update Acknowledge decoding and message transfer
|
||||
*/
|
||||
int DU_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
|
||||
sctp_assoc_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu)
|
||||
{
|
||||
AssertFatal(1==0,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int DU_handle_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
||||
{
|
||||
LOG_D(F1AP, "DU_handle_gNB_CU_CONFIGURATION_UPDATE\n");
|
||||
AssertFatal(pdu->present == F1AP_F1AP_PDU_PR_initiatingMessage,
|
||||
"pdu->present != F1AP_F1AP_PDU_PR_initiatingMessage\n");
|
||||
AssertFatal(pdu->choice.initiatingMessage->procedureCode == F1AP_ProcedureCode_id_gNBCUConfigurationUpdate,
|
||||
"pdu->choice.initiatingMessage->procedureCode != F1AP_ProcedureCode_id_gNBCUConfigurationUpdate\n");
|
||||
AssertFatal(pdu->choice.initiatingMessage->criticality == F1AP_Criticality_reject,
|
||||
"pdu->choice.initiatingMessage->criticality != F1AP_Criticality_reject\n");
|
||||
AssertFatal(pdu->choice.initiatingMessage->value.present == F1AP_InitiatingMessage__value_PR_GNBCUConfigurationUpdate,
|
||||
"pdu->choice.initiatingMessage->value.present != F1AP_InitiatingMessage__value_PR_GNBCUConfigurationUpdate\n");
|
||||
F1AP_GNBCUConfigurationUpdate_t *in = &pdu->choice.initiatingMessage->value.choice.GNBCUConfigurationUpdate;
|
||||
F1AP_GNBCUConfigurationUpdateIEs_t *ie;
|
||||
int TransactionId = -1;
|
||||
int num_cells_to_activate = 0;
|
||||
F1AP_Cells_to_be_Activated_List_Item_t *cell;
|
||||
MessageDef *msg_p = itti_alloc_new_message (TASK_DU_F1, 0, F1AP_GNB_CU_CONFIGURATION_UPDATE);
|
||||
LOG_D(F1AP, "F1AP: gNB_CU_Configuration_Update: protocolIEs.list.count %d\n",
|
||||
in->protocolIEs.list.count);
|
||||
|
||||
for (int i=0; i < in->protocolIEs.list.count; i++) {
|
||||
ie = in->protocolIEs.list.array[i];
|
||||
|
||||
switch (ie->id) {
|
||||
case F1AP_ProtocolIE_ID_id_TransactionID:
|
||||
AssertFatal(ie->criticality == F1AP_Criticality_reject,
|
||||
"ie->criticality != F1AP_Criticality_reject\n");
|
||||
AssertFatal(ie->value.present == F1AP_GNBCUConfigurationUpdateIEs__value_PR_TransactionID,
|
||||
"ie->value.present != F1AP_GNBCUConfigurationUpdateIEs__value_PR_TransactionID\n");
|
||||
TransactionId=ie->value.choice.TransactionID;
|
||||
LOG_D(F1AP, "F1AP: GNB-CU-ConfigurationUpdate: TransactionId %d\n",
|
||||
TransactionId);
|
||||
break;
|
||||
|
||||
case F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List: {
|
||||
AssertFatal(ie->criticality == F1AP_Criticality_reject,
|
||||
"ie->criticality != F1AP_Criticality_reject\n");
|
||||
AssertFatal(ie->value.present == F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Activated_List,
|
||||
"ie->value.present != F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Activated_List\n");
|
||||
num_cells_to_activate = ie->value.choice.Cells_to_be_Activated_List.list.count;
|
||||
LOG_D(F1AP, "F1AP: Activating %d cells\n",num_cells_to_activate);
|
||||
|
||||
for (int i=0; i<num_cells_to_activate; i++) {
|
||||
F1AP_Cells_to_be_Activated_List_ItemIEs_t *cells_to_be_activated_list_item_ies = (F1AP_Cells_to_be_Activated_List_ItemIEs_t *) ie->value.choice.Cells_to_be_Activated_List.list.array[i];
|
||||
AssertFatal(cells_to_be_activated_list_item_ies->id == F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item,
|
||||
"cells_to_be_activated_list_item_ies->id != F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item");
|
||||
AssertFatal(cells_to_be_activated_list_item_ies->criticality == F1AP_Criticality_reject,
|
||||
"cells_to_be_activated_list_item_ies->criticality == F1AP_Criticality_reject");
|
||||
AssertFatal(cells_to_be_activated_list_item_ies->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item,
|
||||
"cells_to_be_activated_list_item_ies->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item");
|
||||
cell = &cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item;
|
||||
TBCD_TO_MCC_MNC(&cell->nRCGI.pLMN_Identity,
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).cells_to_activate[i].plmn.mcc,
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).cells_to_activate[i].plmn.mnc,
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).cells_to_activate[i].plmn.mnc_digit_length);
|
||||
LOG_D(F1AP, "nr_cellId : %x %x %x %x %x\n",
|
||||
cell->nRCGI.nRCellIdentity.buf[0],
|
||||
cell->nRCGI.nRCellIdentity.buf[1],
|
||||
cell->nRCGI.nRCellIdentity.buf[2],
|
||||
cell->nRCGI.nRCellIdentity.buf[3],
|
||||
cell->nRCGI.nRCellIdentity.buf[4]);
|
||||
BIT_STRING_TO_NR_CELL_IDENTITY(&cell->nRCGI.nRCellIdentity,
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].nr_cellid);
|
||||
F1AP_ProtocolExtensionContainer_10696P112_t *ext = (F1AP_ProtocolExtensionContainer_10696P112_t *)cell->iE_Extensions;
|
||||
|
||||
if (ext==NULL)
|
||||
continue;
|
||||
|
||||
for (int cnt=0; cnt<ext->list.count; cnt++) {
|
||||
F1AP_Cells_to_be_Activated_List_ItemExtIEs_t *cells_to_be_activated_list_itemExtIEs=(F1AP_Cells_to_be_Activated_List_ItemExtIEs_t *)ext->list.array[cnt];
|
||||
|
||||
switch (cells_to_be_activated_list_itemExtIEs->id) {
|
||||
/*
|
||||
case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_NOTHING:
|
||||
case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_GNB_CUSystemInformation,
|
||||
case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_AvailablePLMNList,
|
||||
case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_ExtendedAvailablePLMN_List,
|
||||
case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_IAB_Info_IAB_donor_CU,
|
||||
case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_AvailableSNPN_ID_List
|
||||
*/
|
||||
case F1AP_ProtocolIE_ID_id_gNB_CUSystemInformation: {
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].nrpci = (cell->nRPCI != NULL) ? *cell->nRPCI : 0;
|
||||
F1AP_GNB_CUSystemInformation_t *gNB_CUSystemInformation = (F1AP_GNB_CUSystemInformation_t *)&cells_to_be_activated_list_itemExtIEs->extensionValue.choice.GNB_CUSystemInformation;
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].num_SI = gNB_CUSystemInformation->sibtypetobeupdatedlist.list.count;
|
||||
AssertFatal(ext->list.count==1,"At least one SI message should be there, and only 1 for now!\n");
|
||||
LOG_D(F1AP,
|
||||
"F1AP: Cell %d MCC %d MNC %d NRCellid %lx num_si %d\n",
|
||||
i,
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).cells_to_activate[i].plmn.mcc,
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).cells_to_activate[i].plmn.mnc,
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).cells_to_activate[i].nr_cellid,
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).cells_to_activate[i].num_SI);
|
||||
|
||||
for (int si = 0; si < gNB_CUSystemInformation->sibtypetobeupdatedlist.list.count; si++) {
|
||||
F1AP_SibtypetobeupdatedListItem_t *sib_item = gNB_CUSystemInformation->sibtypetobeupdatedlist.list.array[si];
|
||||
size_t size = sib_item->sIBmessage.size;
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].SI_container_length[si] = size;
|
||||
LOG_D(F1AP, "F1AP: SI_container_length[%d][%ld] %ld bytes\n", i, sib_item->sIBtype, size);
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].SI_container[si] = malloc(F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].SI_container_length[si]);
|
||||
memcpy((void *)F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].SI_container[si],
|
||||
(void *)sib_item->sIBmessage.buf,
|
||||
size);
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].SI_type[si]=sib_item->sIBtype;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case F1AP_ProtocolIE_ID_id_AvailablePLMNList:
|
||||
AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n");
|
||||
break;
|
||||
|
||||
case F1AP_ProtocolIE_ID_id_ExtendedAvailablePLMN_List:
|
||||
AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n");
|
||||
break;
|
||||
|
||||
case F1AP_ProtocolIE_ID_id_IAB_Info_IAB_donor_CU:
|
||||
AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n");
|
||||
break;
|
||||
|
||||
case F1AP_ProtocolIE_ID_id_AvailableSNPN_ID_List:
|
||||
AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(1==0,"F1AP_ProtocolIE_ID_id %d unknown\n",(int)cells_to_be_activated_list_itemExtIEs->id);
|
||||
break;
|
||||
}
|
||||
} // for (cnt=...
|
||||
} // for (cells_to_activate...
|
||||
|
||||
break;
|
||||
} // case F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List
|
||||
|
||||
default:
|
||||
AssertFatal(1==0,"F1AP_ProtocolIE_ID_id %d unknown\n", (int)ie->id);
|
||||
break;
|
||||
} // switch ie
|
||||
} // for IE
|
||||
|
||||
AssertFatal(TransactionId!=-1,"TransactionId was not sent\n");
|
||||
LOG_D(F1AP,"F1AP: num_cells_to_activate %d\n",num_cells_to_activate);
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).num_cells_to_activate = num_cells_to_activate;
|
||||
LOG_D(F1AP, "Sending F1AP_GNB_CU_CONFIGURATION_UPDATE ITTI message \n");
|
||||
// Decoding
|
||||
f1ap_gnb_du_configuration_update_acknowledge_t in = {0};
|
||||
if (!decode_f1ap_du_configuration_update_acknowledge(pdu, &in)) {
|
||||
LOG_E(F1AP, "Failed to decode gNB-DU Configuration Update Acknowledge\n");
|
||||
free_f1ap_du_configuration_update_acknowledge(&in);
|
||||
return -1;
|
||||
}
|
||||
// Allocate and send an ITTI message
|
||||
MessageDef *msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE);
|
||||
f1ap_gnb_du_configuration_update_acknowledge_t *msg = &F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg_p);
|
||||
// Copy the decoded message to the ITTI message (RRC thread will free it)
|
||||
*msg = in; // Copy the decoded message to the ITTI message (RRC thread will free it)
|
||||
itti_send_msg_to_task(TASK_GNB_APP, GNB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p);
|
||||
return 0;
|
||||
}
|
||||
@@ -911,62 +275,22 @@ int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(sctp_assoc_t assoc_id,
|
||||
GNBCUConfigurationUpdateFailure->cause);
|
||||
}
|
||||
|
||||
int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(
|
||||
sctp_assoc_t assoc_id,
|
||||
f1ap_gnb_cu_configuration_update_acknowledge_t *GNBCUConfigurationUpdateAcknowledge)
|
||||
/**
|
||||
* @brief Encode and transfer F1 GNB CU Configuration Update Acknowledge message
|
||||
*/
|
||||
int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id, f1ap_gnb_cu_configuration_update_acknowledge_t *msg)
|
||||
{
|
||||
AssertFatal(GNBCUConfigurationUpdateAcknowledge->num_cells_failed_to_be_activated == 0,
|
||||
"%d cells failed to activate\n",
|
||||
GNBCUConfigurationUpdateAcknowledge->num_cells_failed_to_be_activated);
|
||||
AssertFatal(GNBCUConfigurationUpdateAcknowledge->noofTNLAssociations_to_setup == 0,
|
||||
"%d TNLAssociations to setup, handle this ...\n",
|
||||
GNBCUConfigurationUpdateAcknowledge->noofTNLAssociations_to_setup);
|
||||
AssertFatal(GNBCUConfigurationUpdateAcknowledge->noofTNLAssociations_failed == 0,
|
||||
"%d TNLAssociations failed\n",
|
||||
GNBCUConfigurationUpdateAcknowledge->noofTNLAssociations_failed);
|
||||
AssertFatal(GNBCUConfigurationUpdateAcknowledge->noofDedicatedSIDeliveryNeededUEs == 0,
|
||||
"%d DedicatedSIDeliveryNeededUEs\n",
|
||||
GNBCUConfigurationUpdateAcknowledge->noofDedicatedSIDeliveryNeededUEs);
|
||||
F1AP_F1AP_PDU_t pdu= {0};
|
||||
uint8_t *buffer=NULL;
|
||||
uint32_t len=0;
|
||||
/* Create */
|
||||
/* 0. pdu Type */
|
||||
pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome;
|
||||
asn1cCalloc(pdu.choice.successfulOutcome, tmp);
|
||||
tmp->procedureCode = F1AP_ProcedureCode_id_gNBCUConfigurationUpdate;
|
||||
tmp->criticality = F1AP_Criticality_reject;
|
||||
tmp->value.present = F1AP_SuccessfulOutcome__value_PR_GNBCUConfigurationUpdateAcknowledge;
|
||||
F1AP_GNBCUConfigurationUpdateAcknowledge_t *out = &tmp->value.choice.GNBCUConfigurationUpdateAcknowledge;
|
||||
/* mandatory */
|
||||
/* c1. Transaction ID (integer value)*/
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_GNBCUConfigurationUpdateAcknowledgeIEs_t, ie);
|
||||
ie->id = F1AP_ProtocolIE_ID_id_TransactionID;
|
||||
ie->criticality = F1AP_Criticality_reject;
|
||||
ie->value.present = F1AP_GNBCUConfigurationUpdateAcknowledgeIEs__value_PR_TransactionID;
|
||||
ie->value.choice.TransactionID = F1AP_get_next_transaction_identifier(0, 0);
|
||||
|
||||
/* encode */
|
||||
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
LOG_E(F1AP, "Failed to encode GNB-DU-Configuration-Update-Acknowledge\n");
|
||||
uint8_t *buffer = NULL;
|
||||
uint32_t len = 0;
|
||||
/* encode F1 message */
|
||||
F1AP_F1AP_PDU_t *pdu = encode_f1ap_cu_configuration_update_acknowledge(msg);
|
||||
/* encode F1AP PDU */
|
||||
if (!pdu || f1ap_encode_pdu(pdu, &buffer, &len) < 0) {
|
||||
LOG_E(F1AP, "Failed to encode GNB-CU-Configuration-Update-Acknowledge\n");
|
||||
ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu);
|
||||
ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu);
|
||||
f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DU_send_gNB_DU_RESOURCE_COORDINATION_REQUEST(sctp_assoc_t assoc_id,
|
||||
F1AP_GNBDUResourceCoordinationRequest_t *GNBDUResourceCoordinationRequest)
|
||||
{
|
||||
AssertFatal(0, "Not implemented yet\n");
|
||||
}
|
||||
|
||||
int DU_handle_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance,
|
||||
sctp_assoc_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu)
|
||||
{
|
||||
AssertFatal(0, "Not implemented yet\n");
|
||||
}
|
||||
|
||||
@@ -38,14 +38,6 @@
|
||||
*/
|
||||
int DU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
||||
int DU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack);
|
||||
int DU_send_RESET(sctp_assoc_t assoc_id, const f1ap_reset_t *reset);
|
||||
int DU_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
/*
|
||||
* Error Indication
|
||||
*/
|
||||
int DU_send_ERROR_INDICATION(sctp_assoc_t assoc_id, F1AP_F1AP_PDU_t *pdu_p);
|
||||
int DU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
/*
|
||||
* F1 Setup
|
||||
@@ -59,14 +51,7 @@ int DU_handle_F1_SETUP_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint3
|
||||
/*
|
||||
* gNB-DU Configuration Update
|
||||
*/
|
||||
int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, const f1ap_gnb_du_configuration_update_t *upd);
|
||||
|
||||
int DU_handle_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
int DU_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
|
||||
sctp_assoc_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_gnb_du_configuration_update_t *msg);
|
||||
|
||||
/*
|
||||
* gNB-CU Configuration Update
|
||||
@@ -79,17 +64,9 @@ int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(sctp_assoc_t assoc_id,
|
||||
int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id,
|
||||
f1ap_gnb_cu_configuration_update_acknowledge_t *GNBCUConfigurationUpdateAcknowledge);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* gNB-DU Resource Coordination
|
||||
*/
|
||||
int DU_send_gNB_DU_RESOURCE_COORDINATION_REQUEST(sctp_assoc_t assoc_id,
|
||||
F1AP_GNBDUResourceCoordinationRequest_t *GNBDUResourceCoordinationRequest);
|
||||
|
||||
int DU_handle_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance,
|
||||
sctp_assoc_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
int DU_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
|
||||
sctp_assoc_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
#endif /* F1AP_DU_INTERFACE_MANAGEMENT_H_ */
|
||||
|
||||
@@ -53,226 +53,78 @@
|
||||
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h"
|
||||
|
||||
#include "f1ap_rrc_message_transfer.h"
|
||||
|
||||
/* DL RRC Message Transfer */
|
||||
int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
||||
{
|
||||
F1AP_DLRRCMessageTransfer_t *container;
|
||||
F1AP_DLRRCMessageTransferIEs_t *ie;
|
||||
int executeDuplication;
|
||||
//uint64_t subscriberProfileIDforRFP;
|
||||
//uint64_t rAT_FrequencySelectionPriority;
|
||||
DevAssert(pdu != NULL);
|
||||
container = &pdu->choice.initiatingMessage->value.choice.DLRRCMessageTransfer;
|
||||
/* GNB_CU_UE_F1AP_ID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
|
||||
uint32_t cu_ue_f1ap_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
|
||||
/* GNB_DU_UE_F1AP_ID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
|
||||
uint32_t du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
|
||||
|
||||
/* optional */
|
||||
/* oldgNB_DU_UE_F1AP_ID */
|
||||
uint32_t *old_gNB_DU_ue_id = NULL;
|
||||
uint32_t old_gNB_DU_ue_id_stack = 0;
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID, false);
|
||||
if (ie) {
|
||||
/* strange: it is not named OLD_GNB_DU_UE... */
|
||||
old_gNB_DU_ue_id_stack = ie->value.choice.GNB_DU_UE_F1AP_ID_1;
|
||||
old_gNB_DU_ue_id = &old_gNB_DU_ue_id_stack;
|
||||
f1ap_dl_rrc_message_t msg = {0};
|
||||
if (!decode_dl_rrc_message_transfer(pdu, &msg)) {
|
||||
LOG_E(F1AP, "cannot decode F1 DL RRC message Transfer\n");
|
||||
free_dl_rrc_message_transfer(&msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* mandatory */
|
||||
/* SRBID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_SRBID, true);
|
||||
uint64_t srb_id = ie->value.choice.SRBID;
|
||||
LOG_D(F1AP, "srb_id %lu \n", srb_id);
|
||||
|
||||
/* optional */
|
||||
/* ExecuteDuplication */
|
||||
if (0) {
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_ExecuteDuplication, true);
|
||||
executeDuplication = ie->value.choice.ExecuteDuplication;
|
||||
LOG_D(F1AP, "ExecuteDuplication %d \n", executeDuplication);
|
||||
}
|
||||
|
||||
// issue in here
|
||||
/* mandatory */
|
||||
/* RRC Container */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_RRCContainer, true);
|
||||
/* optional */
|
||||
/* RAT_FrequencyPriorityInformation */
|
||||
if (0) {
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_RAT_FrequencyPriorityInformation, true);
|
||||
|
||||
switch(ie->value.choice.RAT_FrequencyPriorityInformation.present) {
|
||||
case F1AP_RAT_FrequencyPriorityInformation_PR_eNDC:
|
||||
//subscriberProfileIDforRFP = ie->value.choice.RAT_FrequencyPriorityInformation.choice.subscriberProfileIDforRFP;
|
||||
break;
|
||||
|
||||
case F1AP_RAT_FrequencyPriorityInformation_PR_nGRAN:
|
||||
//rAT_FrequencySelectionPriority = ie->value.choice.RAT_FrequencyPriorityInformation.choice.rAT_FrequencySelectionPriority;
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_W(F1AP, "unhandled IE RAT_FrequencyPriorityInformation.present\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
f1ap_dl_rrc_message_t dl_rrc = {
|
||||
.gNB_CU_ue_id = cu_ue_f1ap_id,
|
||||
.gNB_DU_ue_id = du_ue_f1ap_id,
|
||||
.old_gNB_DU_ue_id = old_gNB_DU_ue_id,
|
||||
.rrc_container_length = ie->value.choice.RRCContainer.size,
|
||||
.rrc_container = ie->value.choice.RRCContainer.buf,
|
||||
.srb_id = srb_id
|
||||
};
|
||||
dl_rrc_message_transfer(&dl_rrc);
|
||||
dl_rrc_message_transfer(&msg);
|
||||
/* Free DL RRC Message Transfer */
|
||||
free_dl_rrc_message_transfer(&msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* UL RRC Message Transfer */
|
||||
int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, const f1ap_initial_ul_rrc_message_t *msg)
|
||||
{
|
||||
F1AP_F1AP_PDU_t pdu= {0};
|
||||
F1AP_InitialULRRCMessageTransfer_t *out;
|
||||
uint8_t *buffer=NULL;
|
||||
uint32_t len=0;
|
||||
/* encode Initial UL RRC Message Transfer */
|
||||
F1AP_F1AP_PDU_t *pdu = encode_initial_ul_rrc_message_transfer(msg);
|
||||
/* free F1AP message after encoding */
|
||||
free_initial_ul_rrc_message_transfer(msg);
|
||||
|
||||
/* Create */
|
||||
/* 0. Message Type */
|
||||
pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
|
||||
asn1cCalloc(pdu.choice.initiatingMessage, tmp);
|
||||
tmp->procedureCode = F1AP_ProcedureCode_id_InitialULRRCMessageTransfer;
|
||||
tmp->criticality = F1AP_Criticality_ignore;
|
||||
tmp->value.present = F1AP_InitiatingMessage__value_PR_InitialULRRCMessageTransfer;
|
||||
out = &tmp->value.choice.InitialULRRCMessageTransfer;
|
||||
/* mandatory */
|
||||
/* c1. GNB_DU_UE_F1AP_ID */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie1);
|
||||
ie1->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
|
||||
ie1->criticality = F1AP_Criticality_reject;
|
||||
ie1->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID;
|
||||
ie1->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id;
|
||||
/* mandatory */
|
||||
/* c2. NRCGI */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie2);
|
||||
ie2->id = F1AP_ProtocolIE_ID_id_NRCGI;
|
||||
ie2->criticality = F1AP_Criticality_reject;
|
||||
ie2->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_NRCGI;
|
||||
//Fixme: takes always the first cell
|
||||
addnRCGI(ie2->value.choice.NRCGI, &getCxt(0)->setupReq.cell[0].info);
|
||||
/* mandatory */
|
||||
/* c3. C_RNTI */ // 16
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie3);
|
||||
ie3->id = F1AP_ProtocolIE_ID_id_C_RNTI;
|
||||
ie3->criticality = F1AP_Criticality_reject;
|
||||
ie3->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_C_RNTI;
|
||||
ie3->value.choice.C_RNTI = msg->crnti;
|
||||
/* mandatory */
|
||||
/* c4. RRCContainer */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie4);
|
||||
ie4->id = F1AP_ProtocolIE_ID_id_RRCContainer;
|
||||
ie4->criticality = F1AP_Criticality_reject;
|
||||
ie4->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_RRCContainer;
|
||||
OCTET_STRING_fromBuf(&ie4->value.choice.RRCContainer, (const char *)msg->rrc_container, msg->rrc_container_length);
|
||||
|
||||
/* optional */
|
||||
/* c5. DUtoCURRCContainer */
|
||||
if (msg->du2cu_rrc_container != NULL) {
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie5);
|
||||
ie5->id = F1AP_ProtocolIE_ID_id_DUtoCURRCContainer;
|
||||
ie5->criticality = F1AP_Criticality_reject;
|
||||
ie5->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_DUtoCURRCContainer;
|
||||
OCTET_STRING_fromBuf(&ie5->value.choice.DUtoCURRCContainer,
|
||||
(const char *)msg->du2cu_rrc_container,
|
||||
msg->du2cu_rrc_container_length);
|
||||
}
|
||||
/* mandatory */
|
||||
/* c6. Transaction ID (integer value) */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie6);
|
||||
ie6->id = F1AP_ProtocolIE_ID_id_TransactionID;
|
||||
ie6->criticality = F1AP_Criticality_ignore;
|
||||
ie6->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_TransactionID;
|
||||
ie6->value.choice.TransactionID = F1AP_get_next_transaction_identifier(0, 0);
|
||||
|
||||
/* encode */
|
||||
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
LOG_E(F1AP, "Failed to encode F1 INITIAL UL RRC MESSAGE TRANSFER\n");
|
||||
if (pdu == NULL) {
|
||||
LOG_E(F1AP, "cannot encode F1 INITIAL UL RRC MESSAGE TRANSFER, can't send message\n");
|
||||
ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* encode F1AP PDU */
|
||||
uint8_t *buffer = NULL;
|
||||
uint32_t len = 0;
|
||||
if (f1ap_encode_pdu(pdu, &buffer, &len) < 0) {
|
||||
LOG_E(F1AP, "Failed to encode F1 INITIAL UL RRC MESSAGE TRANSFER\n");
|
||||
ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu);
|
||||
return -1;
|
||||
}
|
||||
ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu);
|
||||
|
||||
/* Send to ITTI */
|
||||
f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, const f1ap_ul_rrc_message_t *msg)
|
||||
{
|
||||
F1AP_F1AP_PDU_t pdu= {0};
|
||||
F1AP_ULRRCMessageTransfer_t *out;
|
||||
uint8_t *buffer = NULL;
|
||||
uint32_t len;
|
||||
LOG_D(F1AP,
|
||||
"size %d UE RNTI %x in SRB %d\n",
|
||||
msg->rrc_container_length,
|
||||
msg->gNB_DU_ue_id,
|
||||
msg->srb_id);
|
||||
//for (int i = 0;i < msg->rrc_container_length; i++)
|
||||
// printf("%02x ", msg->rrc_container[i]);
|
||||
//printf("\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;
|
||||
out = &tmp->value.choice.ULRRCMessageTransfer;
|
||||
/* mandatory */
|
||||
/* c1. GNB_CU_UE_F1AP_ID */
|
||||
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;
|
||||
/* mandatory */
|
||||
/* c2. GNB_DU_UE_F1AP_ID */
|
||||
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;
|
||||
/* mandatory */
|
||||
/* c3. SRBID */
|
||||
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;
|
||||
// issue in here
|
||||
/* mandatory */
|
||||
/* c4. RRCContainer */
|
||||
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);
|
||||
|
||||
/* encode */
|
||||
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
LOG_E(F1AP, "Failed to encode F1 UL RRC MESSAGE TRANSFER \n");
|
||||
/* encode UL RRC Message Transfer */
|
||||
F1AP_F1AP_PDU_t *pdu = encode_ul_rrc_message_transfer(msg);
|
||||
if (pdu == NULL) {
|
||||
LOG_E(F1AP, "Failed to encode F1 UL RRC MESSAGE TRANSFER: cannot send message\n");
|
||||
ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* encode F1AP PDU */
|
||||
uint8_t *buffer = NULL;
|
||||
uint32_t len;
|
||||
if (f1ap_encode_pdu(pdu, &buffer, &len) < 0) {
|
||||
LOG_E(F1AP, "Failed to encode F1 UL RRC MESSAGE TRANSFER \n");
|
||||
ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu);
|
||||
return -1;
|
||||
}
|
||||
/* Free F1AP PDU */
|
||||
ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu);
|
||||
/* Send to ITTI */
|
||||
f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file f1ap_du_interface_management.h
|
||||
* \brief f1ap interface management for DU
|
||||
* \author EURECOM/NTUST
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file f1ap_du_interface_management.h
|
||||
* \brief f1ap interface management for DU
|
||||
* \author EURECOM/NTUST
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
@@ -44,7 +44,7 @@ static instance_t du_create_gtpu_instance_to_cu(const f1ap_net_config_t *nc)
|
||||
{
|
||||
openAddr_t tmp = {0};
|
||||
strncpy(tmp.originHost, nc->DU_f1u_ip_address, sizeof(tmp.originHost) - 1);
|
||||
strncpy(tmp.destinationHost, nc->CU_f1_ip_address.ipv4_address, sizeof(tmp.destinationHost) - 1);
|
||||
strncpy(tmp.destinationHost, nc->CU_f1_ip_address, sizeof(tmp.destinationHost) - 1);
|
||||
sprintf(tmp.originService, "%d", nc->DUport);
|
||||
sprintf(tmp.destinationService, "%d", nc->CUport);
|
||||
return gtpv1Init(tmp);
|
||||
@@ -63,9 +63,20 @@ void du_task_send_sctp_association_req(instance_t instance, f1ap_net_config_t *n
|
||||
sctp_new_association_req_p->in_streams = 2; //du_inst->sctp_in_streams;
|
||||
sctp_new_association_req_p->out_streams = 2; //du_inst->sctp_out_streams;
|
||||
// remote
|
||||
memcpy(&sctp_new_association_req_p->remote_address, &nc->CU_f1_ip_address, sizeof(nc->CU_f1_ip_address));
|
||||
sctp_new_association_req_p->remote_address.ipv4 = 1;
|
||||
strncpy(sctp_new_association_req_p->remote_address.ipv4_address,
|
||||
nc->CU_f1_ip_address,
|
||||
sizeof(sctp_new_association_req_p->remote_address.ipv4_address) - 1);
|
||||
// local
|
||||
memcpy(&sctp_new_association_req_p->local_address, &nc->DU_f1c_ip_address, sizeof(nc->DU_f1c_ip_address));
|
||||
sctp_new_association_req_p->local_address.ipv4 = 1;
|
||||
strncpy(sctp_new_association_req_p->local_address.ipv4_address,
|
||||
nc->DU_f1c_ip_address,
|
||||
sizeof(sctp_new_association_req_p->local_address.ipv4_address) - 1);
|
||||
LOG_D(F1AP,
|
||||
"Local IPv4 Address: %s, Remote IPv4 Address: %s\n",
|
||||
sctp_new_association_req_p->local_address.ipv4_address,
|
||||
sctp_new_association_req_p->remote_address.ipv4_address);
|
||||
|
||||
// du_f1ap_register_to_sctp
|
||||
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
|
||||
}
|
||||
@@ -89,6 +100,8 @@ void du_task_handle_sctp_association_resp(instance_t instance, sctp_new_associat
|
||||
f1ap_du_data->du.assoc_id = sctp_new_association_resp->assoc_id;
|
||||
f1ap_du_data->sctp_in_streams = sctp_new_association_resp->in_streams;
|
||||
f1ap_du_data->sctp_out_streams = sctp_new_association_resp->out_streams;
|
||||
/* next transaction ID */
|
||||
f1ap_du_data->setupReq.transaction_id = F1AP_get_next_transaction_identifier(0, 0);
|
||||
/* setup parameters for F1U and start the server */
|
||||
DU_send_F1_SETUP_REQUEST(f1ap_du_data->du.assoc_id, &f1ap_du_data->setupReq);
|
||||
}
|
||||
|
||||
@@ -45,13 +45,13 @@ static void f1ap_read_drb_qos_param(const F1AP_QoSFlowLevelQoSParameters_t *asn1
|
||||
const F1AP_QoS_Characteristics_t *dRB_QoS_Char = &asn1_qos->qoS_Characteristics;
|
||||
|
||||
if (dRB_QoS_Char->present == F1AP_QoS_Characteristics_PR_non_Dynamic_5QI) {
|
||||
drb_qos_char->qos_type = non_dynamic;
|
||||
drb_qos_char->qos_type = NON_DYNAMIC;
|
||||
drb_qos_char->non_dynamic.fiveqi = dRB_QoS_Char->choice.non_Dynamic_5QI->fiveQI;
|
||||
drb_qos_char->non_dynamic.qos_priority_level = (dRB_QoS_Char->choice.non_Dynamic_5QI->qoSPriorityLevel != NULL)
|
||||
? *dRB_QoS_Char->choice.non_Dynamic_5QI->qoSPriorityLevel
|
||||
: -1;
|
||||
} else {
|
||||
drb_qos_char->qos_type = dynamic;
|
||||
drb_qos_char->qos_type = DYNAMIC;
|
||||
drb_qos_char->dynamic.fiveqi =
|
||||
(dRB_QoS_Char->choice.dynamic_5QI->fiveQI != NULL) ? *dRB_QoS_Char->choice.dynamic_5QI->fiveQI : -1;
|
||||
drb_qos_char->dynamic.qos_priority_level = dRB_QoS_Char->choice.dynamic_5QI->qoSPriorityLevel;
|
||||
@@ -84,13 +84,13 @@ static void f1ap_read_flows_mapped(const F1AP_Flows_Mapped_To_DRB_List_t *asn1_f
|
||||
const F1AP_QoS_Characteristics_t *Flow_QoS_Char = &Flow_QoS->qoS_Characteristics;
|
||||
|
||||
if (Flow_QoS_Char->present == F1AP_QoS_Characteristics_PR_non_Dynamic_5QI) {
|
||||
flow_qos_char->qos_type = non_dynamic;
|
||||
flow_qos_char->qos_type = NON_DYNAMIC;
|
||||
flow_qos_char->non_dynamic.fiveqi = Flow_QoS_Char->choice.non_Dynamic_5QI->fiveQI;
|
||||
flow_qos_char->non_dynamic.qos_priority_level = (Flow_QoS_Char->choice.non_Dynamic_5QI->qoSPriorityLevel != NULL)
|
||||
? *Flow_QoS_Char->choice.non_Dynamic_5QI->qoSPriorityLevel
|
||||
: -1;
|
||||
} else {
|
||||
flow_qos_char->qos_type = dynamic;
|
||||
flow_qos_char->qos_type = DYNAMIC;
|
||||
flow_qos_char->dynamic.fiveqi =
|
||||
(Flow_QoS_Char->choice.dynamic_5QI->fiveQI != NULL) ? *Flow_QoS_Char->choice.dynamic_5QI->fiveQI : -1;
|
||||
flow_qos_char->dynamic.qos_priority_level = Flow_QoS_Char->choice.dynamic_5QI->qoSPriorityLevel;
|
||||
@@ -209,11 +209,14 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_i
|
||||
|
||||
switch (drbs_tobesetup_item_p->rLCMode) {
|
||||
case F1AP_RLCMode_rlc_am:
|
||||
drb_p->rlc_mode = RLC_MODE_AM;
|
||||
drb_p->rlc_mode = F1AP_RLC_MODE_AM;
|
||||
break;
|
||||
case F1AP_RLCMode_rlc_um_bidirectional:
|
||||
drb_p->rlc_mode = F1AP_RLC_MODE_UM_BIDIR;
|
||||
break;
|
||||
|
||||
default:
|
||||
drb_p->rlc_mode = RLC_MODE_TM;
|
||||
LOG_W(F1AP, "unsupported RLC Mode %ld received: setting UM bidir\n", drbs_tobesetup_item_p->rLCMode);
|
||||
drb_p->rlc_mode = F1AP_RLC_MODE_UM_BIDIR;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -930,13 +933,16 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t
|
||||
drb_p->up_ul_tnl[0].port = getCxt(instance)->net_config.CUport;
|
||||
|
||||
switch (drbs_tobesetupmod_item_p->rLCMode) {
|
||||
case F1AP_RLCMode_rlc_am:
|
||||
drb_p->rlc_mode = RLC_MODE_AM;
|
||||
break;
|
||||
|
||||
default:
|
||||
drb_p->rlc_mode = RLC_MODE_TM;
|
||||
break;
|
||||
case F1AP_RLCMode_rlc_am:
|
||||
drb_p->rlc_mode = F1AP_RLC_MODE_AM;
|
||||
break;
|
||||
case F1AP_RLCMode_rlc_um_bidirectional:
|
||||
drb_p->rlc_mode = F1AP_RLC_MODE_UM_BIDIR;
|
||||
break;
|
||||
default:
|
||||
LOG_W(F1AP, "unsupported RLC Mode %ld received: setting UM bidir\n", drbs_tobesetupmod_item_p->rLCMode);
|
||||
drb_p->rlc_mode = F1AP_RLC_MODE_UM_BIDIR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (drbs_tobesetupmod_item_p->qoSInformation.present == F1AP_QoSInformation_PR_eUTRANQoS) {
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file f1ap_du_interface_management.h
|
||||
* \brief f1ap interface management for DU
|
||||
* \author EURECOM/NTUST
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
@@ -48,10 +48,8 @@ static const f1ap_message_processing_t f1ap_messages_processing[][3] = {
|
||||
// {CU_handle_RESET, DU_handle_RESET_ACKNOWLEDGE, 0}, /* Reset */
|
||||
{CU_handle_F1_SETUP_REQUEST, DU_handle_F1_SETUP_RESPONSE, DU_handle_F1_SETUP_FAILURE}, /* F1Setup */
|
||||
{0, 0, 0}, /* ErrorIndication */
|
||||
{CU_handle_gNB_DU_CONFIGURATION_UPDATE, 0, 0}, /* gNBDUConfigurationUpdate */
|
||||
{DU_handle_gNB_CU_CONFIGURATION_UPDATE,
|
||||
CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE,
|
||||
CU_handle_gNB_CU_CONFIGURATION_UPDATE_FAILURE}, /* gNBCUConfigurationUpdate */
|
||||
{CU_handle_gNB_DU_CONFIGURATION_UPDATE, DU_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE, 0}, /* gNBDUConfigurationUpdate */
|
||||
{DU_handle_gNB_CU_CONFIGURATION_UPDATE, CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE, 0}, /* gNBCUConfigurationUpdate */
|
||||
{DU_handle_UE_CONTEXT_SETUP_REQUEST, CU_handle_UE_CONTEXT_SETUP_RESPONSE, 0}, /* UEContextSetup */
|
||||
{DU_handle_UE_CONTEXT_RELEASE_COMMAND, CU_handle_UE_CONTEXT_RELEASE_COMPLETE, 0}, /* UEContextRelease */
|
||||
{DU_handle_UE_CONTEXT_MODIFICATION_REQUEST, CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE, 0}, /* UEContextModification */
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
add_library(f1ap_lib OBJECT
|
||||
f1ap_lib_common.c
|
||||
f1ap_rrc_message_transfer.c
|
||||
f1ap_interface_management.c
|
||||
)
|
||||
target_link_libraries(f1ap_lib PRIVATE asn1_f1ap)
|
||||
target_include_directories(f1ap_lib PUBLIC
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef F1AP_INTERFACE_MANAGEMENT_H_
|
||||
#define F1AP_INTERFACE_MANAGEMENT_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "f1ap_messages_types.h"
|
||||
|
||||
struct F1AP_F1AP_PDU;
|
||||
|
||||
struct F1AP_F1AP_PDU *encode_f1ap_setup_request(const f1ap_setup_req_t *msg);
|
||||
bool decode_f1ap_setup_request(const struct F1AP_F1AP_PDU *pdu, f1ap_setup_req_t *out);
|
||||
f1ap_setup_req_t cp_f1ap_setup_request(const f1ap_setup_req_t *msg);
|
||||
bool eq_f1ap_setup_request(const f1ap_setup_req_t *a, const f1ap_setup_req_t *b);
|
||||
void free_f1ap_setup_request(const f1ap_setup_req_t *msg);
|
||||
|
||||
/* F1 Setup Response */
|
||||
struct F1AP_F1AP_PDU *encode_f1ap_setup_response(const f1ap_setup_resp_t *msg);
|
||||
bool decode_f1ap_setup_response(const struct F1AP_F1AP_PDU *pdu, f1ap_setup_resp_t *out);
|
||||
void free_f1ap_setup_response(const f1ap_setup_resp_t *msg);
|
||||
f1ap_setup_resp_t cp_f1ap_setup_response(const f1ap_setup_resp_t *msg);
|
||||
bool eq_f1ap_setup_response(const f1ap_setup_resp_t *a, const f1ap_setup_resp_t *b);
|
||||
|
||||
/* F1 Setup Failure */
|
||||
struct F1AP_F1AP_PDU *encode_f1ap_setup_failure(const f1ap_setup_failure_t *msg);
|
||||
bool decode_f1ap_setup_failure(const struct F1AP_F1AP_PDU *pdu, f1ap_setup_failure_t *out);
|
||||
bool eq_f1ap_setup_failure(const f1ap_setup_failure_t *a, const f1ap_setup_failure_t *b);
|
||||
f1ap_setup_failure_t cp_f1ap_setup_failure(const f1ap_setup_failure_t *msg);
|
||||
|
||||
/* F1 gNB-DU Configuration Update */
|
||||
struct F1AP_F1AP_PDU *encode_f1ap_du_configuration_update(const f1ap_gnb_du_configuration_update_t *msg);
|
||||
bool decode_f1ap_du_configuration_update(const struct F1AP_F1AP_PDU *pdu, f1ap_gnb_du_configuration_update_t *out);
|
||||
bool eq_f1ap_du_configuration_update(const f1ap_gnb_du_configuration_update_t *a, const f1ap_gnb_du_configuration_update_t *b);
|
||||
f1ap_gnb_du_configuration_update_t cp_f1ap_du_configuration_update(const f1ap_gnb_du_configuration_update_t *msg);
|
||||
void free_f1ap_du_configuration_update(const f1ap_gnb_du_configuration_update_t *msg);
|
||||
|
||||
/* F1 gNB-CU Configuration Update */
|
||||
struct F1AP_F1AP_PDU *encode_f1ap_cu_configuration_update(const f1ap_gnb_cu_configuration_update_t *msg);
|
||||
bool decode_f1ap_cu_configuration_update(const struct F1AP_F1AP_PDU *pdu, f1ap_gnb_cu_configuration_update_t *out);
|
||||
bool eq_f1ap_cu_configuration_update(const f1ap_gnb_cu_configuration_update_t *a, const f1ap_gnb_cu_configuration_update_t *b);
|
||||
f1ap_gnb_cu_configuration_update_t cp_f1ap_cu_configuration_update(const f1ap_gnb_cu_configuration_update_t *msg);
|
||||
void free_f1ap_cu_configuration_update(const f1ap_gnb_cu_configuration_update_t *msg);
|
||||
|
||||
/* F1 gNB-CU Configuration Update Acknowledge */
|
||||
struct F1AP_F1AP_PDU *encode_f1ap_cu_configuration_update_acknowledge(const f1ap_gnb_cu_configuration_update_acknowledge_t *msg);
|
||||
bool decode_f1ap_cu_configuration_update_acknowledge(const struct F1AP_F1AP_PDU *pdu,
|
||||
f1ap_gnb_cu_configuration_update_acknowledge_t *out);
|
||||
bool eq_f1ap_cu_configuration_update_acknowledge(const f1ap_gnb_cu_configuration_update_acknowledge_t *a,
|
||||
const f1ap_gnb_cu_configuration_update_acknowledge_t *b);
|
||||
f1ap_gnb_cu_configuration_update_acknowledge_t cp_f1ap_cu_configuration_update_acknowledge(
|
||||
const f1ap_gnb_cu_configuration_update_acknowledge_t *msg);
|
||||
|
||||
/* F1 gNB-DU Configuration Update Acknowledge */
|
||||
struct F1AP_F1AP_PDU *encode_f1ap_du_configuration_update_acknowledge(const f1ap_gnb_du_configuration_update_acknowledge_t *msg);
|
||||
bool decode_f1ap_du_configuration_update_acknowledge(const struct F1AP_F1AP_PDU *pdu,
|
||||
f1ap_gnb_du_configuration_update_acknowledge_t *out);
|
||||
bool eq_f1ap_du_configuration_update_acknowledge(const f1ap_gnb_du_configuration_update_acknowledge_t *a,
|
||||
const f1ap_gnb_du_configuration_update_acknowledge_t *b);
|
||||
f1ap_gnb_du_configuration_update_acknowledge_t cp_f1ap_du_configuration_update_acknowledge(
|
||||
const f1ap_gnb_du_configuration_update_acknowledge_t *msg);
|
||||
void free_f1ap_du_configuration_update_acknowledge(const f1ap_gnb_du_configuration_update_acknowledge_t *msg);
|
||||
|
||||
#endif /* F1AP_INTERFACE_MANAGEMENT_H_ */
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "f1ap_lib_common.h"
|
||||
#include "f1ap_messages_types.h"
|
||||
|
||||
#include "OCTET_STRING.h"
|
||||
#include "common/utils/utils.h"
|
||||
#include "common/utils/assertions.h"
|
||||
#include "common/utils/utils.h"
|
||||
|
||||
bool eq_f1ap_plmn(const f1ap_plmn_t *a, const f1ap_plmn_t *b)
|
||||
{
|
||||
_F1_EQ_CHECK_INT(a->mcc, b->mcc);
|
||||
_F1_EQ_CHECK_INT(a->mnc, b->mnc);
|
||||
_F1_EQ_CHECK_INT(a->mnc_digit_length, b->mnc_digit_length);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool eq_f1ap_freq_info(const f1ap_nr_frequency_info_t *a, const f1ap_nr_frequency_info_t *b)
|
||||
{
|
||||
if (a->arfcn != b->arfcn)
|
||||
return false;
|
||||
if (a->band != b->band)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool eq_f1ap_tx_bandwidth(const f1ap_transmission_bandwidth_t *a, const f1ap_transmission_bandwidth_t *b)
|
||||
{
|
||||
if (a->nrb != b->nrb)
|
||||
return false;
|
||||
if (a->scs != b->scs)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool eq_f1ap_cell_info(const f1ap_served_cell_info_t *a, const f1ap_served_cell_info_t *b)
|
||||
{
|
||||
if (a->nr_cellid != b->nr_cellid)
|
||||
return false;
|
||||
if (a->nr_pci != b->nr_pci)
|
||||
return false;
|
||||
if (*a->tac != *b->tac)
|
||||
return false;
|
||||
if (a->mode != b->mode)
|
||||
return false;
|
||||
if (a->mode == F1AP_MODE_TDD) {
|
||||
/* TDD */
|
||||
if (!eq_f1ap_tx_bandwidth(&a->tdd.tbw, &b->tdd.tbw))
|
||||
return false;
|
||||
if (!eq_f1ap_freq_info(&a->tdd.freqinfo, &b->tdd.freqinfo))
|
||||
return false;
|
||||
} else if (a->mode == F1AP_MODE_FDD) {
|
||||
/* FDD */
|
||||
if (!eq_f1ap_tx_bandwidth(&a->fdd.dl_tbw, &b->fdd.dl_tbw))
|
||||
return false;
|
||||
if (!eq_f1ap_freq_info(&a->fdd.dl_freqinfo, &b->fdd.dl_freqinfo))
|
||||
return false;
|
||||
if (!eq_f1ap_tx_bandwidth(&a->fdd.ul_tbw, &b->fdd.ul_tbw))
|
||||
return false;
|
||||
if (!eq_f1ap_freq_info(&a->fdd.ul_freqinfo, &b->fdd.ul_freqinfo))
|
||||
return false;
|
||||
}
|
||||
if (a->measurement_timing_config_len != b->measurement_timing_config_len)
|
||||
return false;
|
||||
if (*a->measurement_timing_config != *b->measurement_timing_config)
|
||||
return false;
|
||||
if (!eq_f1ap_plmn(&a->plmn, &b->plmn))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool eq_f1ap_sys_info(const f1ap_gnb_du_system_info_t *a, const f1ap_gnb_du_system_info_t *b)
|
||||
{
|
||||
/* MIB */
|
||||
if (a->mib_length != b->mib_length)
|
||||
return false;
|
||||
for (int i = 0; i < a->mib_length; i++) {
|
||||
if (a->mib[i] != b->mib[i])
|
||||
return false;
|
||||
}
|
||||
/* SIB1 */
|
||||
if (a->sib1_length != b->sib1_length)
|
||||
return false;
|
||||
for (int i = 0; i < a->sib1_length; i++) {
|
||||
if (a->sib1[i] != b->sib1[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t *cp_octet_string(const OCTET_STRING_t *os, int *len)
|
||||
{
|
||||
uint8_t *buf = calloc_or_fail(os->size, sizeof(*buf));
|
||||
memcpy(buf, os->buf, os->size);
|
||||
*len = os->size;
|
||||
return buf;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef F1AP_LIB_COMMON_H_
|
||||
#define F1AP_LIB_COMMON_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "openair3/UTILS/conversions.h"
|
||||
|
||||
#ifdef ENABLE_TESTS
|
||||
#define PRINT_ERROR(...) fprintf(stderr, ##__VA_ARGS__)
|
||||
#else
|
||||
#define PRINT_ERROR(...) // Do nothing
|
||||
#endif
|
||||
|
||||
#define _F1_EQ_CHECK_GENERIC(condition, fmt, ...) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
PRINT_ERROR("F1 Equality Check failure: %s:%d: Condition '%s' failed: " fmt " != " fmt "\n", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
#condition, \
|
||||
##__VA_ARGS__); \
|
||||
return false; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define _F1_EQ_CHECK_LONG(A, B) _F1_EQ_CHECK_GENERIC(A == B, "%ld", A, B);
|
||||
#define _F1_EQ_CHECK_INT(A, B) _F1_EQ_CHECK_GENERIC(A == B, "%d", A, B);
|
||||
#define _F1_EQ_CHECK_STR(A, B) _F1_EQ_CHECK_GENERIC(strcmp(A, B) == 0, "'%s'", A, B);
|
||||
|
||||
/* macro to look up IE. If mandatory and not found, macro will print
|
||||
* descriptive debug message to stderr and force exit in calling function */
|
||||
#define F1AP_LIB_FIND_IE(IE_TYPE, ie, container, IE_ID, mandatory) \
|
||||
do { \
|
||||
ie = NULL; \
|
||||
for (IE_TYPE **ptr = container->protocolIEs.list.array; \
|
||||
ptr < &container->protocolIEs.list.array[container->protocolIEs.list.count]; \
|
||||
ptr++) { \
|
||||
if ((*ptr)->id == IE_ID) { \
|
||||
ie = *ptr; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
if (mandatory && ie == NULL) { \
|
||||
fprintf(stderr, "%s(): could not find element " #IE_ID " with type " #IE_TYPE "\n", __func__); \
|
||||
return false; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
struct f1ap_plmn_t;
|
||||
bool eq_f1ap_plmn(const struct f1ap_plmn_t *a, const struct f1ap_plmn_t *b);
|
||||
struct f1ap_served_cell_info_t;
|
||||
bool eq_f1ap_cell_info(const struct f1ap_served_cell_info_t *a, const struct f1ap_served_cell_info_t *b);
|
||||
struct f1ap_gnb_du_system_info_t;
|
||||
bool eq_f1ap_sys_info(const struct f1ap_gnb_du_system_info_t *a, const struct f1ap_gnb_du_system_info_t *b);
|
||||
struct f1ap_nr_frequency_info_t;
|
||||
bool eq_f1ap_freq_info(const struct f1ap_nr_frequency_info_t *a, const struct f1ap_nr_frequency_info_t *b);
|
||||
struct f1ap_transmission_bandwidth_t;
|
||||
bool eq_f1ap_tx_bandwidth(const struct f1ap_transmission_bandwidth_t *a, const struct f1ap_transmission_bandwidth_t *b);
|
||||
|
||||
struct OCTET_STRING;
|
||||
uint8_t *cp_octet_string(const struct OCTET_STRING *os, int *len);
|
||||
|
||||
#endif /* F1AP_LIB_COMMON_H_ */
|
||||
+6
-10
@@ -19,13 +19,9 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file f1ap_du_interface_management.h
|
||||
* \brief f1ap interface management for DU
|
||||
* \author EURECOM/NTUST
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#ifndef F1AP_LIB_EXTERN_H_
|
||||
#define F1AP_LIB_EXTERN_H_
|
||||
|
||||
#include "f1ap_rrc_message_transfer.h"
|
||||
|
||||
#endif /* F1AP_LIB_EXTERN_H_ */
|
||||
+23
-10
@@ -19,13 +19,26 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file f1ap_du_interface_management.h
|
||||
* \brief f1ap interface management for DU
|
||||
* \author EURECOM/NTUST
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#ifndef F1AP_LIB_INCLUDES_H_
|
||||
#define F1AP_LIB_INCLUDES_H_
|
||||
|
||||
#include "F1AP_F1AP-PDU.h"
|
||||
#include "F1AP_InitialULRRCMessageTransfer.h"
|
||||
#include "F1AP_InitiatingMessage.h"
|
||||
#include "F1AP_NRCellIdentity.h"
|
||||
#include "F1AP_ProtocolIE-Field.h"
|
||||
#include "F1AP_ServedPLMNs-Item.h"
|
||||
#include "F1AP_ProtocolExtensionContainer.h"
|
||||
#include "F1AP_ProtocolExtensionField.h"
|
||||
#include "F1AP_ProtocolIE-Field.h"
|
||||
#include "F1AP_SliceSupportItem.h"
|
||||
#include "F1AP_NR-Mode-Info.h"
|
||||
#include "F1AP_GNB-DU-System-Information.h"
|
||||
#include "F1AP_FDD-Info.h"
|
||||
#include "F1AP_TDD-Info.h"
|
||||
#include "F1AP_FreqBandNrItem.h"
|
||||
#include "F1AP_SuccessfulOutcome.h"
|
||||
#include "F1AP_SibtypetobeupdatedListItem.h"
|
||||
#include "F1AP_UnsuccessfulOutcome.h"
|
||||
|
||||
#endif /* F1AP_LIB_INCLUDES_H_ */
|
||||
@@ -0,0 +1,479 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "f1ap_rrc_message_transfer.h"
|
||||
|
||||
#include "f1ap_lib_common.h"
|
||||
#include "f1ap_lib_includes.h"
|
||||
#include "f1ap_messages_types.h"
|
||||
|
||||
#include "common/utils/assertions.h"
|
||||
#include "openair3/UTILS/conversions.h"
|
||||
#include "common/utils/oai_asn1.h"
|
||||
#include "common/utils/utils.h"
|
||||
|
||||
/* ====================================
|
||||
* F1AP Initial UL RRC Message Transfer
|
||||
* ==================================== */
|
||||
|
||||
/**
|
||||
* @brief Initial UL RRC Message Transfer encoding
|
||||
*/
|
||||
F1AP_F1AP_PDU_t *encode_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *msg)
|
||||
{
|
||||
F1AP_F1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu));
|
||||
|
||||
/* 0. Message Type */
|
||||
pdu->present = F1AP_F1AP_PDU_PR_initiatingMessage;
|
||||
asn1cCalloc(pdu->choice.initiatingMessage, tmp);
|
||||
tmp->procedureCode = F1AP_ProcedureCode_id_InitialULRRCMessageTransfer;
|
||||
tmp->criticality = F1AP_Criticality_ignore;
|
||||
tmp->value.present = F1AP_InitiatingMessage__value_PR_InitialULRRCMessageTransfer;
|
||||
F1AP_InitialULRRCMessageTransfer_t *out = &tmp->value.choice.InitialULRRCMessageTransfer;
|
||||
|
||||
/* mandatory */
|
||||
/* c1. GNB_DU_UE_F1AP_ID */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie1);
|
||||
ie1->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
|
||||
ie1->criticality = F1AP_Criticality_reject;
|
||||
ie1->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID;
|
||||
ie1->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id;
|
||||
|
||||
/* mandatory */
|
||||
/* c2. NRCGI */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie2);
|
||||
ie2->id = F1AP_ProtocolIE_ID_id_NRCGI;
|
||||
ie2->criticality = F1AP_Criticality_reject;
|
||||
ie2->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_NRCGI;
|
||||
MCC_MNC_TO_PLMNID(msg->plmn.mcc, msg->plmn.mnc, msg->plmn.mnc_digit_length, &ie2->value.choice.NRCGI.pLMN_Identity);
|
||||
NR_CELL_ID_TO_BIT_STRING(msg->nr_cellid, &ie2->value.choice.NRCGI.nRCellIdentity);
|
||||
|
||||
/* mandatory */
|
||||
/* c3. C_RNTI */ // 16
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie3);
|
||||
ie3->id = F1AP_ProtocolIE_ID_id_C_RNTI;
|
||||
ie3->criticality = F1AP_Criticality_reject;
|
||||
ie3->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_C_RNTI;
|
||||
ie3->value.choice.C_RNTI = msg->crnti;
|
||||
|
||||
/* mandatory */
|
||||
/* c4. RRCContainer */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie4);
|
||||
ie4->id = F1AP_ProtocolIE_ID_id_RRCContainer;
|
||||
ie4->criticality = F1AP_Criticality_reject;
|
||||
ie4->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_RRCContainer;
|
||||
OCTET_STRING_fromBuf(&ie4->value.choice.RRCContainer, (const char *)msg->rrc_container, msg->rrc_container_length);
|
||||
|
||||
/* optional */
|
||||
/* c5. DUtoCURRCContainer */
|
||||
if (msg->du2cu_rrc_container != NULL) {
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie5);
|
||||
ie5->id = F1AP_ProtocolIE_ID_id_DUtoCURRCContainer;
|
||||
ie5->criticality = F1AP_Criticality_reject;
|
||||
ie5->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_DUtoCURRCContainer;
|
||||
OCTET_STRING_fromBuf(&ie5->value.choice.DUtoCURRCContainer,
|
||||
(const char *)msg->du2cu_rrc_container,
|
||||
msg->du2cu_rrc_container_length);
|
||||
}
|
||||
|
||||
/* mandatory */
|
||||
/* c6. Transaction ID (integer value) */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie6);
|
||||
ie6->id = F1AP_ProtocolIE_ID_id_TransactionID;
|
||||
ie6->criticality = F1AP_Criticality_ignore;
|
||||
ie6->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_TransactionID;
|
||||
ie6->value.choice.TransactionID = msg->transaction_id;
|
||||
|
||||
return pdu;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initial UL RRC Message Transfer decoding
|
||||
*/
|
||||
bool decode_initial_ul_rrc_message_transfer(const F1AP_F1AP_PDU_t *pdu, f1ap_initial_ul_rrc_message_t *out)
|
||||
{
|
||||
DevAssert(out != NULL);
|
||||
memset(out, 0, sizeof(*out));
|
||||
|
||||
F1AP_InitialULRRCMessageTransfer_t *container = &pdu->choice.initiatingMessage->value.choice.InitialULRRCMessageTransfer;
|
||||
F1AP_InitialULRRCMessageTransferIEs_t *ie;
|
||||
|
||||
F1AP_LIB_FIND_IE(F1AP_InitialULRRCMessageTransferIEs_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;
|
||||
|
||||
F1AP_LIB_FIND_IE(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_NRCGI, true);
|
||||
PLMNID_TO_MCC_MNC(&ie->value.choice.NRCGI.pLMN_Identity, out->plmn.mcc, out->plmn.mnc, out->plmn.mnc_digit_length);
|
||||
BIT_STRING_TO_NR_CELL_IDENTITY(&ie->value.choice.NRCGI.nRCellIdentity, out->nr_cellid);
|
||||
|
||||
F1AP_LIB_FIND_IE(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_C_RNTI, true);
|
||||
out->crnti = ie->value.choice.C_RNTI;
|
||||
|
||||
F1AP_LIB_FIND_IE(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_RRCContainer, true);
|
||||
out->rrc_container = cp_octet_string(&ie->value.choice.RRCContainer, &out->rrc_container_length);
|
||||
|
||||
F1AP_LIB_FIND_IE(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_DUtoCURRCContainer, false);
|
||||
if (ie != NULL)
|
||||
out->du2cu_rrc_container = cp_octet_string(&ie->value.choice.DUtoCURRCContainer, &out->du2cu_rrc_container_length);
|
||||
|
||||
F1AP_LIB_FIND_IE(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_TransactionID, true);
|
||||
out->transaction_id = ie->value.choice.TransactionID;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initial UL RRC Message Transfer deep copy
|
||||
*/
|
||||
f1ap_initial_ul_rrc_message_t cp_initial_ul_rrc_message_transfer(const f1ap_initial_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);
|
||||
uint8_t *du2cu_rrc_container = NULL;
|
||||
if (msg->du2cu_rrc_container_length > 0) {
|
||||
DevAssert(msg->du2cu_rrc_container != NULL);
|
||||
du2cu_rrc_container = calloc_or_fail(msg->du2cu_rrc_container_length, sizeof(*du2cu_rrc_container));
|
||||
memcpy(du2cu_rrc_container, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length);
|
||||
}
|
||||
f1ap_initial_ul_rrc_message_t cp = {
|
||||
.gNB_DU_ue_id = msg->gNB_DU_ue_id,
|
||||
.plmn = msg->plmn,
|
||||
.nr_cellid = msg->nr_cellid,
|
||||
.crnti = msg->crnti,
|
||||
.rrc_container = rrc_container,
|
||||
.rrc_container_length = msg->rrc_container_length,
|
||||
.du2cu_rrc_container = du2cu_rrc_container,
|
||||
.du2cu_rrc_container_length = msg->du2cu_rrc_container_length,
|
||||
.transaction_id = msg->transaction_id
|
||||
};
|
||||
return cp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initial UL RRC Message Transfer equality check
|
||||
*/
|
||||
bool eq_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *a, const f1ap_initial_ul_rrc_message_t *b)
|
||||
{
|
||||
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
|
||||
if (!eq_f1ap_plmn(&a->plmn, &b->plmn))
|
||||
return false;
|
||||
_F1_EQ_CHECK_LONG(a->nr_cellid, b->nr_cellid);
|
||||
_F1_EQ_CHECK_INT(a->crnti, b->crnti);
|
||||
_F1_EQ_CHECK_INT(a->rrc_container_length, b->rrc_container_length);
|
||||
_F1_EQ_CHECK_LONG(a->nr_cellid, b->nr_cellid);
|
||||
if (memcmp(a->rrc_container, b->rrc_container, a->rrc_container_length) != 0)
|
||||
return false;
|
||||
_F1_EQ_CHECK_INT(a->du2cu_rrc_container_length, b->du2cu_rrc_container_length);
|
||||
if (memcmp(a->du2cu_rrc_container, b->du2cu_rrc_container, a->du2cu_rrc_container_length) != 0)
|
||||
return false;
|
||||
_F1_EQ_CHECK_INT(a->transaction_id, b->transaction_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initial UL RRC Message Transfer memory management
|
||||
*/
|
||||
void free_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *msg)
|
||||
{
|
||||
DevAssert(msg != NULL);
|
||||
free(msg->rrc_container);
|
||||
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
|
||||
* ============================ */
|
||||
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef F1AP_RRC_MESSAGE_TRANSFER_H_
|
||||
#define F1AP_RRC_MESSAGE_TRANSFER_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "f1ap_messages_types.h"
|
||||
|
||||
struct F1AP_F1AP_PDU;
|
||||
|
||||
struct F1AP_F1AP_PDU *encode_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *msg);
|
||||
bool decode_initial_ul_rrc_message_transfer(const struct F1AP_F1AP_PDU *pdu, f1ap_initial_ul_rrc_message_t *out);
|
||||
f1ap_initial_ul_rrc_message_t cp_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *msg);
|
||||
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);
|
||||
|
||||
/* 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_ */
|
||||
@@ -0,0 +1,6 @@
|
||||
add_executable(f1ap_lib_test f1ap_lib_test.c)
|
||||
add_dependencies(tests f1ap_lib_test)
|
||||
add_test(NAME f1ap_lib_test COMMAND f1ap_lib_test)
|
||||
target_link_libraries(f1ap_lib_test PRIVATE f1ap_lib)
|
||||
target_link_libraries(f1ap_lib_test PRIVATE asn1_f1ap)
|
||||
target_include_directories(f1ap_lib_test PRIVATE ${CMAKE_SOURCE_DIR})
|
||||
@@ -0,0 +1,564 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "common/utils/assertions.h"
|
||||
#include "common/utils/utils.h"
|
||||
|
||||
#include "f1ap_messages_types.h"
|
||||
#include "F1AP_F1AP-PDU.h"
|
||||
|
||||
#include "f1ap_lib_extern.h"
|
||||
#include "lib/f1ap_interface_management.h"
|
||||
|
||||
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
|
||||
{
|
||||
printf("detected error at %s:%d:%s: %s\n", file, line, function, s);
|
||||
abort();
|
||||
}
|
||||
|
||||
static F1AP_F1AP_PDU_t *f1ap_encode_decode(const F1AP_F1AP_PDU_t *enc_pdu)
|
||||
{
|
||||
//xer_fprint(stdout, &asn_DEF_F1AP_F1AP_PDU, enc_pdu);
|
||||
|
||||
DevAssert(enc_pdu != NULL);
|
||||
char errbuf[1024];
|
||||
size_t errlen = sizeof(errbuf);
|
||||
int ret = asn_check_constraints(&asn_DEF_F1AP_F1AP_PDU, enc_pdu, errbuf, &errlen);
|
||||
AssertFatal(ret == 0, "asn_check_constraints() failed: %s\n", errbuf);
|
||||
|
||||
uint8_t msgbuf[16384];
|
||||
asn_enc_rval_t enc = aper_encode_to_buffer(&asn_DEF_F1AP_F1AP_PDU, NULL, enc_pdu, msgbuf, sizeof(msgbuf));
|
||||
AssertFatal(enc.encoded > 0, "aper_encode_to_buffer() failed\n");
|
||||
|
||||
F1AP_F1AP_PDU_t *dec_pdu = NULL;
|
||||
asn_codec_ctx_t st = {.max_stack_size = 100 * 1000};
|
||||
asn_dec_rval_t dec = aper_decode(&st, &asn_DEF_F1AP_F1AP_PDU, (void **)&dec_pdu, msgbuf, enc.encoded, 0, 0);
|
||||
AssertFatal(dec.code == RC_OK, "aper_decode() failed\n");
|
||||
|
||||
//xer_fprint(stdout, &asn_DEF_F1AP_F1AP_PDU, dec_pdu);
|
||||
return dec_pdu;
|
||||
}
|
||||
|
||||
static void f1ap_msg_free(F1AP_F1AP_PDU_t *pdu)
|
||||
{
|
||||
ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test Initial UL RRC Message Transfer encoding/decoding
|
||||
*/
|
||||
static void test_initial_ul_rrc_message_transfer(void)
|
||||
{
|
||||
f1ap_plmn_t plmn = { .mcc = 208, .mnc = 95, .mnc_digit_length = 2 };
|
||||
uint8_t rrc[] = "RRC Container";
|
||||
uint8_t du2cu[] = "DU2CU Container";
|
||||
f1ap_initial_ul_rrc_message_t orig = {
|
||||
.gNB_DU_ue_id = 12,
|
||||
.plmn = plmn,
|
||||
.nr_cellid = 135,
|
||||
.crnti = 0x1234,
|
||||
.rrc_container = rrc,
|
||||
.rrc_container_length = sizeof(rrc),
|
||||
.du2cu_rrc_container = du2cu,
|
||||
.du2cu_rrc_container_length = sizeof(du2cu),
|
||||
.transaction_id = 2,
|
||||
};
|
||||
|
||||
F1AP_F1AP_PDU_t *f1enc = encode_initial_ul_rrc_message_transfer(&orig);
|
||||
F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc);
|
||||
f1ap_msg_free(f1enc);
|
||||
|
||||
f1ap_initial_ul_rrc_message_t decoded;
|
||||
bool ret = decode_initial_ul_rrc_message_transfer(f1dec, &decoded);
|
||||
AssertFatal(ret, "decode_initial_ul_rrc_message_transfer(): could not decode message\n");
|
||||
f1ap_msg_free(f1dec);
|
||||
|
||||
ret = eq_initial_ul_rrc_message_transfer(&orig, &decoded);
|
||||
AssertFatal(ret, "eq_initial_ul_rrc_message_transfer(): decoded message doesn't match\n");
|
||||
free_initial_ul_rrc_message_transfer(&decoded);
|
||||
|
||||
f1ap_initial_ul_rrc_message_t cp = cp_initial_ul_rrc_message_transfer(&orig);
|
||||
ret = eq_initial_ul_rrc_message_transfer(&orig, &cp);
|
||||
AssertFatal(ret, "eq_initial_ul_rrc_message_transfer(): copied message doesn't match\n");
|
||||
free_initial_ul_rrc_message_transfer(&cp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test DL RRC Message Transfer encoding/decoding
|
||||
*/
|
||||
static void test_dl_rrc_message_transfer(void)
|
||||
{
|
||||
uint8_t *rrc = calloc(strlen("RRC Container") + 1, sizeof(uint8_t));
|
||||
uint32_t *old_gNB_DU_ue_id = calloc(1, sizeof(uint32_t));
|
||||
AssertFatal(rrc != NULL && old_gNB_DU_ue_id != NULL, "out of memory\n");
|
||||
memcpy((void *)rrc, "RRC Container", strlen("RRC Container") + 1);
|
||||
|
||||
f1ap_dl_rrc_message_t orig = {
|
||||
.gNB_DU_ue_id = 12,
|
||||
.gNB_CU_ue_id = 12,
|
||||
.old_gNB_DU_ue_id = old_gNB_DU_ue_id,
|
||||
.srb_id = 1,
|
||||
.rrc_container = rrc,
|
||||
.rrc_container_length = sizeof(rrc),
|
||||
};
|
||||
|
||||
F1AP_F1AP_PDU_t *f1enc = encode_dl_rrc_message_transfer(&orig);
|
||||
F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc);
|
||||
f1ap_msg_free(f1enc);
|
||||
|
||||
f1ap_dl_rrc_message_t decoded = {0};
|
||||
bool ret = decode_dl_rrc_message_transfer(f1dec, &decoded);
|
||||
AssertFatal(ret, "decode_initial_ul_rrc_message_transfer(): could not decode message\n");
|
||||
f1ap_msg_free(f1dec);
|
||||
|
||||
ret = eq_dl_rrc_message_transfer(&orig, &decoded);
|
||||
AssertFatal(ret, "eq_dl_rrc_message_transfer(): decoded message doesn't match\n");
|
||||
free_dl_rrc_message_transfer(&decoded);
|
||||
|
||||
f1ap_dl_rrc_message_t cp = cp_dl_rrc_message_transfer(&orig);
|
||||
ret = eq_dl_rrc_message_transfer(&orig, &cp);
|
||||
AssertFatal(ret, "eq_dl_rrc_message_transfer(): copied message doesn't match\n");
|
||||
free_dl_rrc_message_transfer(&orig);
|
||||
free_dl_rrc_message_transfer(&cp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test UL RRC Message Transfer encoding/decoding
|
||||
*/
|
||||
static void test_ul_rrc_message_transfer(void)
|
||||
{
|
||||
uint8_t rrc[] = "RRC Container";
|
||||
|
||||
f1ap_ul_rrc_message_t orig = {
|
||||
.gNB_DU_ue_id = 12,
|
||||
.gNB_CU_ue_id = 12,
|
||||
.srb_id = 1,
|
||||
.rrc_container = rrc,
|
||||
.rrc_container_length = sizeof(rrc),
|
||||
};
|
||||
|
||||
F1AP_F1AP_PDU_t *f1enc = encode_ul_rrc_message_transfer(&orig);
|
||||
F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc);
|
||||
f1ap_msg_free(f1enc);
|
||||
|
||||
f1ap_ul_rrc_message_t decoded = {0};
|
||||
bool ret = decode_ul_rrc_message_transfer(f1dec, &decoded);
|
||||
AssertFatal(ret, "decode_initial_ul_rrc_message_transfer(): could not decode message\n");
|
||||
f1ap_msg_free(f1dec);
|
||||
|
||||
ret = eq_ul_rrc_message_transfer(&orig, &decoded);
|
||||
AssertFatal(ret, "eq_dl_rrc_message_transfer(): decoded message doesn't match\n");
|
||||
free_ul_rrc_message_transfer(&decoded);
|
||||
|
||||
f1ap_ul_rrc_message_t cp = cp_ul_rrc_message_transfer(&orig);
|
||||
ret = eq_ul_rrc_message_transfer(&orig, &cp);
|
||||
AssertFatal(ret, "eq_dl_rrc_message_transfer(): copied message doesn't match\n");
|
||||
free_ul_rrc_message_transfer(&cp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test F1AP Setup Request Encoding/Decoding
|
||||
*/
|
||||
static void test_f1ap_setup_request(void)
|
||||
{
|
||||
/* allocate memory */
|
||||
/* gNB_DU_name */
|
||||
uint8_t *gNB_DU_name = calloc(strlen("OAI DU") + 1, sizeof(uint8_t));
|
||||
AssertFatal(gNB_DU_name != NULL, "out of memory\n");
|
||||
memcpy((void *)gNB_DU_name, "OAI DU", strlen("OAI DU") + 1);
|
||||
/* sys_info */
|
||||
uint8_t *mib = calloc(3, sizeof(uint8_t));
|
||||
uint8_t *sib1 = calloc(3, sizeof(uint8_t));
|
||||
f1ap_gnb_du_system_info_t sys_info = {
|
||||
.mib_length = 3,
|
||||
.mib = mib,
|
||||
.sib1_length = 3,
|
||||
.sib1 = sib1,
|
||||
};
|
||||
/* measurement_timing_information */
|
||||
int measurement_timing_config_len = strlen("0") + 1;
|
||||
uint8_t *measurement_timing_information = calloc(measurement_timing_config_len, sizeof(uint8_t));
|
||||
AssertFatal(measurement_timing_information != NULL, "out of memory\n");
|
||||
memcpy((void *)measurement_timing_information, "0", measurement_timing_config_len);
|
||||
/* TAC */
|
||||
uint32_t *tac = calloc(1, sizeof(uint32_t));
|
||||
/*
|
||||
* TDD test
|
||||
*/
|
||||
// Served Cell Info
|
||||
f1ap_served_cell_info_t info = {
|
||||
.mode = F1AP_MODE_TDD,
|
||||
.tdd.freqinfo.arfcn = 640000,
|
||||
.tdd.freqinfo.band = 78,
|
||||
.tdd.tbw.nrb = 66,
|
||||
.tdd.tbw.scs = 1,
|
||||
.measurement_timing_config_len = measurement_timing_config_len,
|
||||
.measurement_timing_config = measurement_timing_information,
|
||||
.nr_cellid = 123456,
|
||||
.plmn.mcc = 1,
|
||||
.plmn.mnc = 1,
|
||||
.plmn.mnc_digit_length = 3,
|
||||
.num_ssi = 1,
|
||||
.nssai[0].sst = 1,
|
||||
.nssai[0].sd = 1,
|
||||
.tac = tac,
|
||||
};
|
||||
// create message
|
||||
f1ap_setup_req_t orig = {
|
||||
.gNB_DU_id = 1,
|
||||
.gNB_DU_name = (char *)gNB_DU_name,
|
||||
.num_cells_available = 1,
|
||||
.transaction_id = 2,
|
||||
.rrc_ver[0] = 12,
|
||||
.rrc_ver[1] = 34,
|
||||
.rrc_ver[2] = 56,
|
||||
.cell[0].info = info,
|
||||
};
|
||||
orig.cell[0].sys_info = calloc(1, sizeof(*orig.cell[0].sys_info));
|
||||
*orig.cell[0].sys_info = sys_info;
|
||||
// encode
|
||||
F1AP_F1AP_PDU_t *f1enc = encode_f1ap_setup_request(&orig);
|
||||
F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc);
|
||||
f1ap_msg_free(f1enc);
|
||||
// decode
|
||||
f1ap_setup_req_t decoded = {0};
|
||||
bool ret = decode_f1ap_setup_request(f1dec, &decoded);
|
||||
AssertFatal(ret, "decode_f1ap_setup_request(): could not decode message\n");
|
||||
f1ap_msg_free(f1dec);
|
||||
// equality check
|
||||
ret = eq_f1ap_setup_request(&orig, &decoded);
|
||||
AssertFatal(ret, "eq_f1ap_setup_request(): decoded message doesn't match\n");
|
||||
free_f1ap_setup_request(&decoded);
|
||||
// deep copy
|
||||
f1ap_setup_req_t cp = cp_f1ap_setup_request(&orig);
|
||||
ret = eq_f1ap_setup_request(&orig, &cp);
|
||||
AssertFatal(ret, "eq_f1ap_setup_request(): copied message doesn't match\n");
|
||||
free_f1ap_setup_request(&cp);
|
||||
/*
|
||||
* FDD test
|
||||
*/
|
||||
info.mode = F1AP_MODE_FDD;
|
||||
info.tdd.freqinfo.arfcn = 0;
|
||||
info.tdd.freqinfo.band = 0;
|
||||
info.tdd.tbw.nrb = 0;
|
||||
info.tdd.tbw.scs = 0;
|
||||
info.fdd.ul_freqinfo.arfcn = 640000;
|
||||
info.fdd.ul_freqinfo.band = 78;
|
||||
info.fdd.dl_freqinfo.arfcn = 641000;
|
||||
info.fdd.dl_freqinfo.band = 78;
|
||||
info.fdd.ul_tbw.nrb = 66;
|
||||
info.fdd.ul_tbw.scs = 1;
|
||||
info.fdd.dl_tbw.nrb = 66;
|
||||
info.fdd.dl_tbw.scs = 1;
|
||||
// encode
|
||||
f1enc = encode_f1ap_setup_request(&orig);
|
||||
f1dec = f1ap_encode_decode(f1enc);
|
||||
f1ap_msg_free(f1enc);
|
||||
// decode
|
||||
ret = decode_f1ap_setup_request(f1dec, &decoded);
|
||||
AssertFatal(ret, "decode_f1ap_setup_request(): could not decode message\n");
|
||||
f1ap_msg_free(f1dec);
|
||||
// equality check
|
||||
ret = eq_f1ap_setup_request(&orig, &decoded);
|
||||
AssertFatal(ret, "eq_f1ap_setup_request(): decoded message doesn't match\n");
|
||||
free_f1ap_setup_request(&decoded);
|
||||
// copy
|
||||
cp = cp_f1ap_setup_request(&orig);
|
||||
ret = eq_f1ap_setup_request(&orig, &cp);
|
||||
AssertFatal(ret, "eq_f1ap_setup_request(): copied message doesn't match\n");
|
||||
free_f1ap_setup_request(&cp);
|
||||
// free original message
|
||||
free_f1ap_setup_request(&orig);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test F1AP Setup Response Encoding/Decoding
|
||||
*/
|
||||
static void test_f1ap_setup_response(void)
|
||||
{
|
||||
/* allocate memory */
|
||||
/* gNB_CU_name */
|
||||
char *cu_name = "OAI-CU";
|
||||
int len = strlen(cu_name) + 1;
|
||||
uint8_t *gNB_CU_name = calloc(len, sizeof(uint8_t));
|
||||
AssertFatal(gNB_CU_name != NULL, "out of memory\n");
|
||||
memcpy((void *)gNB_CU_name, cu_name, len);
|
||||
/* create message */
|
||||
f1ap_setup_resp_t orig = {
|
||||
.gNB_CU_name = (char *)gNB_CU_name,
|
||||
.transaction_id = 2,
|
||||
.rrc_ver[0] = 12,
|
||||
.rrc_ver[1] = 34,
|
||||
.rrc_ver[2] = 56,
|
||||
.num_cells_to_activate = 1,
|
||||
.cells_to_activate[0].nr_cellid = 123456,
|
||||
.cells_to_activate[0].nrpci = 1,
|
||||
.cells_to_activate[0].plmn.mcc = 12,
|
||||
.cells_to_activate[0].plmn.mnc = 123,
|
||||
.cells_to_activate[0].plmn.mnc_digit_length = 3,
|
||||
};
|
||||
/* Cells to activate */
|
||||
if (orig.num_cells_to_activate) {
|
||||
/* SI_container */
|
||||
char *s = "test";
|
||||
int SI_container_length = strlen(s) + 1;
|
||||
orig.cells_to_activate[0].num_SI = 1;
|
||||
f1ap_sib_msg_t *SI_msg = &orig.cells_to_activate[0].SI_msg[0];
|
||||
SI_msg->SI_container = malloc_or_fail(SI_container_length);
|
||||
memcpy(SI_msg->SI_container, (uint8_t *)s, SI_container_length);
|
||||
SI_msg->SI_container_length = SI_container_length;
|
||||
SI_msg->SI_type = 7;
|
||||
}
|
||||
F1AP_F1AP_PDU_t *f1enc = encode_f1ap_setup_response(&orig);
|
||||
F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc);
|
||||
f1ap_msg_free(f1enc);
|
||||
|
||||
f1ap_setup_resp_t decoded = {0};
|
||||
bool ret = decode_f1ap_setup_response(f1dec, &decoded);
|
||||
AssertFatal(ret, "decode_f1ap_setup_response(): could not decode message\n");
|
||||
f1ap_msg_free(f1dec);
|
||||
|
||||
ret = eq_f1ap_setup_response(&orig, &decoded);
|
||||
AssertFatal(ret, "eq_f1ap_setup_response(): decoded message doesn't match\n");
|
||||
free_f1ap_setup_response(&decoded);
|
||||
|
||||
f1ap_setup_resp_t cp = cp_f1ap_setup_response(&orig);
|
||||
ret = eq_f1ap_setup_response(&orig, &cp);
|
||||
AssertFatal(ret, "eq_f1ap_setup_response(): copied message doesn't match\n");
|
||||
free_f1ap_setup_response(&cp);
|
||||
free_f1ap_setup_response(&orig);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test F1AP Setup Failure Encoding/Decoding
|
||||
*/
|
||||
static void test_f1ap_setup_failure(void)
|
||||
{
|
||||
/* create message */
|
||||
f1ap_setup_failure_t orig = {
|
||||
.transaction_id = 2,
|
||||
.cause = 4,
|
||||
};
|
||||
F1AP_F1AP_PDU_t *f1enc = encode_f1ap_setup_failure(&orig);
|
||||
F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc);
|
||||
f1ap_msg_free(f1enc);
|
||||
|
||||
f1ap_setup_failure_t decoded = {0};
|
||||
bool ret = decode_f1ap_setup_failure(f1dec, &decoded);
|
||||
AssertFatal(ret, "decode_f1ap_setup_failure(): could not decode message\n");
|
||||
f1ap_msg_free(f1dec);
|
||||
|
||||
ret = eq_f1ap_setup_failure(&orig, &decoded);
|
||||
AssertFatal(ret, "eq_f1ap_setup_failure(): decoded message doesn't match\n");
|
||||
|
||||
f1ap_setup_failure_t cp = cp_f1ap_setup_failure(&orig);
|
||||
ret = eq_f1ap_setup_failure(&orig, &cp);
|
||||
AssertFatal(ret, "eq_f1ap_setup_failure(): copied message doesn't match\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test F1 gNB-DU Configuration Update
|
||||
*/
|
||||
static void test_f1ap_du_configuration_update(void)
|
||||
{
|
||||
/* sys_info */
|
||||
uint8_t *mib = calloc(3, sizeof(uint8_t));
|
||||
uint8_t *sib1 = calloc(3, sizeof(uint8_t));
|
||||
f1ap_gnb_du_system_info_t sys_info = {
|
||||
.mib_length = 3,
|
||||
.mib = mib,
|
||||
.sib1_length = 3,
|
||||
.sib1 = sib1,
|
||||
};
|
||||
/* measurement_timing_information modify */
|
||||
char *s = "1";
|
||||
int measurement_timing_config_len = strlen(s) + 1;
|
||||
uint8_t *measurement_timing_config_mod = calloc(measurement_timing_config_len, sizeof(uint8_t));
|
||||
AssertFatal(measurement_timing_config_mod != NULL, "out of memory\n");
|
||||
memcpy((void *)measurement_timing_config_mod, s, measurement_timing_config_len);
|
||||
/* TAC modify */
|
||||
uint32_t *tac = calloc(1, sizeof(uint32_t));
|
||||
AssertFatal(tac != NULL, "out of memory\n");
|
||||
*tac = 456;
|
||||
/* info modify */
|
||||
f1ap_served_cell_info_t info = {
|
||||
.mode = F1AP_MODE_TDD,
|
||||
.tdd.freqinfo.arfcn = 640000,
|
||||
.tdd.freqinfo.band = 78,
|
||||
.tdd.tbw.nrb = 66,
|
||||
.tdd.tbw.scs = 1,
|
||||
.measurement_timing_config_len = measurement_timing_config_len,
|
||||
.measurement_timing_config = measurement_timing_config_mod,
|
||||
.nr_cellid = 123456,
|
||||
.plmn.mcc = 1,
|
||||
.plmn.mnc = 1,
|
||||
.plmn.mnc_digit_length = 3,
|
||||
.tac = tac,
|
||||
};
|
||||
/* create message */
|
||||
f1ap_gnb_du_configuration_update_t orig = {
|
||||
.transaction_id = 2,
|
||||
.num_cells_to_modify = 1,
|
||||
.cell_to_modify[0].info = info,
|
||||
.num_cells_to_delete = 0,
|
||||
.cell_to_delete[0].nr_cellid = 1234UL,
|
||||
.cell_to_delete[0].plmn.mcc = 1,
|
||||
.cell_to_delete[0].plmn.mnc = 1,
|
||||
.cell_to_delete[0].plmn.mnc_digit_length = 3,
|
||||
};
|
||||
orig.cell_to_modify[0].sys_info = calloc(1, sizeof(*orig.cell_to_modify[0].sys_info));
|
||||
AssertFatal(orig.cell_to_modify[0].sys_info != NULL, "out of memory\n");
|
||||
*orig.cell_to_modify[0].sys_info = sys_info;
|
||||
|
||||
F1AP_F1AP_PDU_t *f1enc = encode_f1ap_du_configuration_update(&orig);
|
||||
F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc);
|
||||
f1ap_msg_free(f1enc);
|
||||
|
||||
f1ap_gnb_du_configuration_update_t decoded = {0};
|
||||
bool ret = decode_f1ap_du_configuration_update(f1dec, &decoded);
|
||||
AssertFatal(ret, "decode_f1ap_setup_request(): could not decode message\n");
|
||||
f1ap_msg_free(f1dec);
|
||||
|
||||
ret = eq_f1ap_du_configuration_update(&orig, &decoded);
|
||||
AssertFatal(ret, "eq_f1ap_setup_request(): decoded message doesn't match\n");
|
||||
free_f1ap_du_configuration_update(&decoded);
|
||||
|
||||
f1ap_gnb_du_configuration_update_t cp = cp_f1ap_du_configuration_update(&orig);
|
||||
ret = eq_f1ap_du_configuration_update(&orig, &cp);
|
||||
AssertFatal(ret, "eq_f1ap_setup_request(): copied message doesn't match\n");
|
||||
free_f1ap_du_configuration_update(&cp);
|
||||
free_f1ap_du_configuration_update(&orig);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test F1 gNB-DU Configuration Update Acknowledge
|
||||
*/
|
||||
static void test_f1ap_du_configuration_update_acknowledge(void)
|
||||
{
|
||||
// Create message
|
||||
f1ap_gnb_du_configuration_update_acknowledge_t orig = {
|
||||
.transaction_id = 5,
|
||||
.num_cells_to_activate = 1,
|
||||
.cells_to_activate = {{
|
||||
.nr_cellid = 987654321,
|
||||
.nrpci = 50,
|
||||
.plmn = {.mcc = 001, .mnc = 01, .mnc_digit_length = 2},
|
||||
.num_SI = 1,
|
||||
.SI_msg = {{
|
||||
.SI_type = 7,
|
||||
.SI_container_length = 10,
|
||||
.SI_container = malloc(sizeof(uint8_t) * 10),
|
||||
}},
|
||||
}},
|
||||
};
|
||||
for (int i = 0; i < orig.cells_to_activate[0].SI_msg[0].SI_container_length; i++) {
|
||||
orig.cells_to_activate[0].SI_msg[0].SI_container[i] = i;
|
||||
}
|
||||
// ASN.1 enc/dec
|
||||
F1AP_F1AP_PDU_t *f1enc = encode_f1ap_du_configuration_update_acknowledge(&orig);
|
||||
F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc);
|
||||
f1ap_msg_free(f1enc);
|
||||
// Decoding
|
||||
f1ap_gnb_du_configuration_update_acknowledge_t decoded = {0};
|
||||
bool ret = decode_f1ap_du_configuration_update_acknowledge(f1dec, &decoded);
|
||||
AssertFatal(ret, "decode_f1ap_du_configuration_update_acknowledge(): could not decode message\n");
|
||||
f1ap_msg_free(f1dec);
|
||||
// Equality check
|
||||
ret = eq_f1ap_du_configuration_update_acknowledge(&orig, &decoded);
|
||||
AssertFatal(ret, "eq_f1ap_du_configuration_update_acknowledge(): decoded message doesn't match\n");
|
||||
free_f1ap_du_configuration_update_acknowledge(&decoded);
|
||||
// Deep copy
|
||||
f1ap_gnb_du_configuration_update_acknowledge_t cp = cp_f1ap_du_configuration_update_acknowledge(&orig);
|
||||
ret = eq_f1ap_du_configuration_update_acknowledge(&orig, &cp);
|
||||
AssertFatal(ret, "eq_f1ap_du_configuration_update_acknowledge(): copied message doesn't match\n");
|
||||
// Free
|
||||
free_f1ap_du_configuration_update_acknowledge(&cp);
|
||||
free_f1ap_du_configuration_update_acknowledge(&orig);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test F1 gNB-CU Configuration Update
|
||||
*/
|
||||
static void test_f1ap_cu_configuration_update(void)
|
||||
{
|
||||
/* create message */
|
||||
f1ap_gnb_cu_configuration_update_t orig = {.transaction_id = 2,
|
||||
.num_cells_to_activate = 1,
|
||||
.cells_to_activate = {{.nr_cellid = 123456789,
|
||||
.nrpci = 100,
|
||||
.plmn = {.mcc = 001, .mnc = 01, .mnc_digit_length = 2},
|
||||
.num_SI = 1,
|
||||
.SI_msg = {{
|
||||
.SI_type = 7,
|
||||
.SI_container_length = 10,
|
||||
.SI_container = malloc(sizeof(uint8_t) * 10),
|
||||
}}}}};
|
||||
F1AP_F1AP_PDU_t *f1enc = encode_f1ap_cu_configuration_update(&orig);
|
||||
F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc);
|
||||
f1ap_msg_free(f1enc);
|
||||
|
||||
f1ap_gnb_cu_configuration_update_t decoded = {0};
|
||||
bool ret = decode_f1ap_cu_configuration_update(f1dec, &decoded);
|
||||
AssertFatal(ret, "decode_f1ap_setup_request(): could not decode message\n");
|
||||
f1ap_msg_free(f1dec);
|
||||
|
||||
ret = eq_f1ap_cu_configuration_update(&orig, &decoded);
|
||||
AssertFatal(ret, "eq_f1ap_setup_request(): decoded message doesn't match\n");
|
||||
free_f1ap_cu_configuration_update(&decoded);
|
||||
|
||||
f1ap_gnb_cu_configuration_update_t cp = cp_f1ap_cu_configuration_update(&orig);
|
||||
ret = eq_f1ap_cu_configuration_update(&orig, &cp);
|
||||
AssertFatal(ret, "eq_f1ap_setup_request(): copied message doesn't match\n");
|
||||
free_f1ap_cu_configuration_update(&cp);
|
||||
free_f1ap_cu_configuration_update(&orig);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test F1 gNB-CU Configuration Update Acknowledge
|
||||
*/
|
||||
static void test_f1ap_cu_configuration_update_acknowledge(void)
|
||||
{
|
||||
// Create the original message
|
||||
f1ap_gnb_cu_configuration_update_acknowledge_t orig = {
|
||||
.transaction_id = 2,
|
||||
.num_cells_failed_to_be_activated = 1,
|
||||
.cells_failed_to_be_activated = {{.nr_cellid = 123456789,
|
||||
.plmn = {.mcc = 001, .mnc = 01, .mnc_digit_length = 2},
|
||||
.cause = F1AP_CAUSE_RADIO_NETWORK}}
|
||||
};
|
||||
// F1AP Enc/dec
|
||||
F1AP_F1AP_PDU_t *f1enc = encode_f1ap_cu_configuration_update_acknowledge(&orig);
|
||||
F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc);
|
||||
f1ap_msg_free(f1enc);
|
||||
// Decoding
|
||||
f1ap_gnb_cu_configuration_update_acknowledge_t decoded = {0};
|
||||
bool ret = decode_f1ap_cu_configuration_update_acknowledge(f1dec, &decoded);
|
||||
AssertFatal(ret, "decode_f1ap_cu_configuration_update_acknowledge(): could not decode message\n");
|
||||
f1ap_msg_free(f1dec);
|
||||
// Equality check
|
||||
ret = eq_f1ap_cu_configuration_update_acknowledge(&orig, &decoded);
|
||||
AssertFatal(ret, "eq_f1ap_cu_configuration_update_acknowledge(): decoded message doesn't match\n");
|
||||
// No free needed
|
||||
// Deep copy
|
||||
f1ap_gnb_cu_configuration_update_acknowledge_t cp = cp_f1ap_cu_configuration_update_acknowledge(&orig);
|
||||
// Equality check
|
||||
ret = eq_f1ap_cu_configuration_update_acknowledge(&orig, &cp);
|
||||
AssertFatal(ret, "eq_f1ap_cu_configuration_update_acknowledge(): copied message doesn't match\n");
|
||||
// No free needed
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_initial_ul_rrc_message_transfer();
|
||||
test_dl_rrc_message_transfer();
|
||||
test_ul_rrc_message_transfer();
|
||||
test_f1ap_setup_request();
|
||||
test_f1ap_setup_response();
|
||||
test_f1ap_setup_failure();
|
||||
test_f1ap_du_configuration_update();
|
||||
test_f1ap_cu_configuration_update();
|
||||
test_f1ap_cu_configuration_update_acknowledge();
|
||||
test_f1ap_du_configuration_update_acknowledge();
|
||||
return 0;
|
||||
}
|
||||
@@ -236,10 +236,10 @@ void *gNB_app_task(void *args_p)
|
||||
|
||||
case F1AP_GNB_CU_CONFIGURATION_UPDATE:
|
||||
AssertFatal(NODE_IS_DU(node_type), "Should not have received F1AP_GNB_CU_CONFIGURATION_UPDATE in CU/gNB\n");
|
||||
|
||||
LOG_I(GNB_APP, "Received %s: associated ngran_gNB_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p),
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).gNB_CU_name,F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).num_cells_to_activate);
|
||||
|
||||
LOG_I(GNB_APP,
|
||||
"Received %s: associated with %d cells to activate\n",
|
||||
ITTI_MSG_NAME(msg_p),
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).num_cells_to_activate);
|
||||
cell_to_activate += F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).num_cells_to_activate;
|
||||
gNB_app_handle_f1ap_gnb_cu_configuration_update(&F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p));
|
||||
|
||||
@@ -247,6 +247,11 @@ void *gNB_app_task(void *args_p)
|
||||
AssertFatal(cell_to_activate == 1,"No cells to activate or cells > 1 %d\n",cell_to_activate);
|
||||
|
||||
break;
|
||||
|
||||
case F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE:
|
||||
LOG_E(GNB_APP, "[gNB %ld] Handling of %s message not implemented yet\n", instance, msg_name);
|
||||
break;
|
||||
|
||||
case NGAP_DEREGISTERED_GNB_IND:
|
||||
LOG_W(GNB_APP, "[gNB %ld] Received %s: associated AMF %d\n", instance, msg_name,
|
||||
NGAP_DEREGISTERED_GNB_IND(msg_p).nb_amf);
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
#ifdef ENABLE_AERIAL
|
||||
#include "nfapi/oai_integration/aerial/fapi_vnf_p5.h"
|
||||
#endif
|
||||
#include "lib/f1ap_interface_management.h"
|
||||
|
||||
extern uint16_t sf_ahead;
|
||||
|
||||
@@ -2396,7 +2397,6 @@ int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_up
|
||||
ret++;
|
||||
mac->f1_config.setup_resp = malloc(sizeof(*mac->f1_config.setup_resp));
|
||||
AssertFatal(mac->f1_config.setup_resp != NULL, "out of memory\n");
|
||||
mac->f1_config.setup_resp->gNB_CU_name = gnb_cu_cfg_update->gNB_CU_name;
|
||||
mac->f1_config.setup_resp->num_cells_to_activate = gnb_cu_cfg_update->num_cells_to_activate;
|
||||
mac->f1_config.setup_resp->cells_to_activate[0] = gnb_cu_cfg_update->cells_to_activate[0];
|
||||
} else {
|
||||
@@ -2405,6 +2405,8 @@ int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_up
|
||||
}
|
||||
}
|
||||
NR_SCHED_UNLOCK(&mac->sched_lock);
|
||||
/* Free F1AP struct after use */
|
||||
free_f1ap_cu_configuration_update(gnb_cu_cfg_update);
|
||||
MessageDef *msg_ack_p = NULL;
|
||||
if (ret > 0) {
|
||||
// generate gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE
|
||||
@@ -2414,6 +2416,7 @@ int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_up
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg_ack_p).noofTNLAssociations_to_setup =0;
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg_ack_p).noofTNLAssociations_failed = 0;
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg_ack_p).noofDedicatedSIDeliveryNeededUEs = 0;
|
||||
F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg_ack_p).transaction_id = F1AP_get_next_transaction_identifier(0, 0);
|
||||
itti_send_msg_to_task (TASK_DU_F1, INSTANCE_DEFAULT, msg_ack_p);
|
||||
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "F1AP_CauseRadioNetwork.h"
|
||||
#include "openair3/ocp-gtpu/gtp_itf.h"
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
|
||||
#include "lib/f1ap_interface_management.h"
|
||||
|
||||
#include "executables/softmodem-common.h"
|
||||
|
||||
@@ -169,10 +170,10 @@ void f1_setup_response(const f1ap_setup_resp_t *resp)
|
||||
|
||||
mac->f1_config.setup_resp = malloc(sizeof(*mac->f1_config.setup_resp));
|
||||
AssertFatal(mac->f1_config.setup_resp != NULL, "out of memory\n");
|
||||
*mac->f1_config.setup_resp = *resp;
|
||||
if (resp->gNB_CU_name)
|
||||
mac->f1_config.setup_resp->gNB_CU_name = strdup(resp->gNB_CU_name);
|
||||
|
||||
// Copy F1AP message
|
||||
*mac->f1_config.setup_resp = cp_f1ap_setup_response(resp);
|
||||
// free F1AP message after copy
|
||||
free_f1ap_setup_response(resp);
|
||||
NR_SCHED_UNLOCK(&mac->sched_lock);
|
||||
|
||||
// NOTE: Before accepting any UEs, we should initialize the UE states.
|
||||
@@ -244,7 +245,7 @@ static int handle_ue_context_srbs_setup(NR_UE_info_t *UE,
|
||||
|
||||
static NR_RLC_BearerConfig_t *get_bearerconfig_from_drb(const f1ap_drb_to_be_setup_t *drb)
|
||||
{
|
||||
const NR_RLC_Config_PR rlc_conf = drb->rlc_mode == RLC_MODE_UM ? NR_RLC_Config_PR_um_Bi_Directional : NR_RLC_Config_PR_am;
|
||||
const NR_RLC_Config_PR rlc_conf = drb->rlc_mode == F1AP_RLC_MODE_AM ? NR_RLC_Config_PR_am : NR_RLC_Config_PR_um_Bi_Directional;
|
||||
long priority = 13; // hardcoded for the moment
|
||||
return get_DRB_RLC_BearerConfig(get_lcid_from_drbid(drb->drb_id), drb->drb_id, rlc_conf, priority);
|
||||
}
|
||||
@@ -262,11 +263,11 @@ static NR_QoS_config_t get_qos_config(const f1ap_qos_characteristics_t *qos_char
|
||||
{
|
||||
NR_QoS_config_t qos_c = {0};
|
||||
switch (qos_char->qos_type) {
|
||||
case dynamic:
|
||||
case DYNAMIC:
|
||||
qos_c.priority = qos_char->dynamic.qos_priority_level;
|
||||
qos_c.fiveQI = qos_char->dynamic.fiveqi > 0 ? qos_char->dynamic.fiveqi : 0;
|
||||
break;
|
||||
case non_dynamic:
|
||||
case NON_DYNAMIC:
|
||||
qos_c.fiveQI = qos_char->non_dynamic.fiveqi;
|
||||
qos_c.priority = get_non_dynamic_priority(qos_char->non_dynamic.fiveqi);
|
||||
break;
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#include "intertask_interface.h"
|
||||
|
||||
#include "mac_rrc_ul.h"
|
||||
#include "f1ap_lib_extern.h"
|
||||
#include "lib/f1ap_interface_management.h"
|
||||
|
||||
static void f1_reset_du_initiated_direct(const f1ap_reset_t *reset)
|
||||
{
|
||||
@@ -40,47 +42,8 @@ static void f1_setup_request_direct(const f1ap_setup_req_t *req)
|
||||
{
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_SETUP_REQ);
|
||||
msg->ittiMsgHeader.originInstance = -1; // means monolithic
|
||||
f1ap_setup_req_t *f1ap_msg = &F1AP_SETUP_REQ(msg);
|
||||
f1ap_msg->gNB_DU_id = req->gNB_DU_id;
|
||||
f1ap_msg->gNB_DU_name = strdup(req->gNB_DU_name);
|
||||
f1ap_msg->num_cells_available = req->num_cells_available;
|
||||
for (int n = 0; n < req->num_cells_available; ++n) {
|
||||
f1ap_msg->cell[n].info = req->cell[n].info; // copy most fields
|
||||
if (req->cell[n].info.tac) {
|
||||
f1ap_msg->cell[n].info.tac = malloc(sizeof(*f1ap_msg->cell[n].info.tac));
|
||||
AssertFatal(f1ap_msg->cell[n].info.tac != NULL, "out of memory\n");
|
||||
*f1ap_msg->cell[n].info.tac = *req->cell[n].info.tac;
|
||||
}
|
||||
if (req->cell[n].info.measurement_timing_config_len > 0) {
|
||||
f1ap_msg->cell[n].info.measurement_timing_config = calloc(req->cell[n].info.measurement_timing_config_len, sizeof(uint8_t));
|
||||
AssertFatal(f1ap_msg->cell[n].info.measurement_timing_config != NULL, "out of memory\n");
|
||||
memcpy(f1ap_msg->cell[n].info.measurement_timing_config,
|
||||
req->cell[n].info.measurement_timing_config,
|
||||
req->cell[n].info.measurement_timing_config_len);
|
||||
f1ap_msg->cell[n].info.measurement_timing_config_len = req->cell[n].info.measurement_timing_config_len;
|
||||
}
|
||||
|
||||
if (req->cell[n].sys_info) {
|
||||
f1ap_gnb_du_system_info_t *orig_sys_info = req->cell[n].sys_info;
|
||||
f1ap_gnb_du_system_info_t *copy_sys_info = calloc(1, sizeof(*copy_sys_info));
|
||||
AssertFatal(copy_sys_info, "out of memory\n");
|
||||
f1ap_msg->cell[n].sys_info = copy_sys_info;
|
||||
|
||||
copy_sys_info->mib = calloc(orig_sys_info->mib_length, sizeof(uint8_t));
|
||||
AssertFatal(copy_sys_info->mib, "out of memory\n");
|
||||
memcpy(copy_sys_info->mib, orig_sys_info->mib, orig_sys_info->mib_length);
|
||||
copy_sys_info->mib_length = orig_sys_info->mib_length;
|
||||
|
||||
if (orig_sys_info->sib1_length > 0) {
|
||||
copy_sys_info->sib1 = calloc(orig_sys_info->sib1_length, sizeof(uint8_t));
|
||||
AssertFatal(copy_sys_info->sib1, "out of memory\n");
|
||||
memcpy(copy_sys_info->sib1, orig_sys_info->sib1, orig_sys_info->sib1_length);
|
||||
copy_sys_info->sib1_length = orig_sys_info->sib1_length;
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy(f1ap_msg->rrc_ver, req->rrc_ver, sizeof(req->rrc_ver));
|
||||
|
||||
f1ap_setup_req_t cp = cp_f1ap_setup_request(req);
|
||||
F1AP_SETUP_REQ(msg) = cp;
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, 0, msg);
|
||||
}
|
||||
|
||||
@@ -88,51 +51,8 @@ static void gnb_du_configuration_update_direct(const f1ap_gnb_du_configuration_u
|
||||
{
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_GNB_DU_CONFIGURATION_UPDATE);
|
||||
msg->ittiMsgHeader.originInstance = -1; // means monolithic
|
||||
f1ap_gnb_du_configuration_update_t *f1ap_msg = &F1AP_GNB_DU_CONFIGURATION_UPDATE(msg);
|
||||
DevAssert(upd->gNB_DU_ID == NULL);
|
||||
f1ap_msg->transaction_id = upd->transaction_id;
|
||||
DevAssert(upd->num_cells_to_add == 0);
|
||||
DevAssert(upd->num_cells_to_delete == 0);
|
||||
|
||||
f1ap_msg->num_cells_to_modify = upd->num_cells_to_modify;
|
||||
for (int n = 0; n < upd->num_cells_to_modify; ++n) {
|
||||
f1ap_msg->cell_to_modify[n].old_nr_cellid = upd->cell_to_modify[n].old_nr_cellid;
|
||||
f1ap_msg->cell_to_modify[n].info = upd->cell_to_modify[n].info; // copy most fields
|
||||
if (upd->cell_to_modify[n].info.tac) {
|
||||
f1ap_msg->cell_to_modify[n].info.tac = malloc(sizeof(*f1ap_msg->cell_to_modify[n].info.tac));
|
||||
AssertFatal(f1ap_msg->cell_to_modify[n].info.tac != NULL, "out of memory\n");
|
||||
*f1ap_msg->cell_to_modify[n].info.tac = *upd->cell_to_modify[n].info.tac;
|
||||
}
|
||||
if (upd->cell_to_modify[n].info.measurement_timing_config_len > 0) {
|
||||
f1ap_msg->cell_to_modify[n].info.measurement_timing_config =
|
||||
calloc(upd->cell_to_modify[n].info.measurement_timing_config_len, sizeof(uint8_t));
|
||||
AssertFatal(f1ap_msg->cell_to_modify[n].info.measurement_timing_config != NULL, "out of memory\n");
|
||||
memcpy(f1ap_msg->cell_to_modify[n].info.measurement_timing_config,
|
||||
upd->cell_to_modify[n].info.measurement_timing_config,
|
||||
upd->cell_to_modify[n].info.measurement_timing_config_len);
|
||||
f1ap_msg->cell_to_modify[n].info.measurement_timing_config_len = upd->cell_to_modify[n].info.measurement_timing_config_len;
|
||||
}
|
||||
|
||||
if (upd->cell_to_modify[n].sys_info) {
|
||||
f1ap_gnb_du_system_info_t *orig_sys_info = upd->cell_to_modify[n].sys_info;
|
||||
f1ap_gnb_du_system_info_t *copy_sys_info = calloc(1, sizeof(*copy_sys_info));
|
||||
AssertFatal(copy_sys_info != NULL, "out of memory\n");
|
||||
f1ap_msg->cell_to_modify[n].sys_info = copy_sys_info;
|
||||
|
||||
copy_sys_info->mib = calloc(orig_sys_info->mib_length, sizeof(uint8_t));
|
||||
AssertFatal(copy_sys_info->mib != NULL, "out of memory\n");
|
||||
memcpy(copy_sys_info->mib, orig_sys_info->mib, orig_sys_info->mib_length);
|
||||
copy_sys_info->mib_length = orig_sys_info->mib_length;
|
||||
|
||||
if (orig_sys_info->sib1_length > 0) {
|
||||
copy_sys_info->sib1 = calloc(orig_sys_info->sib1_length, sizeof(uint8_t));
|
||||
AssertFatal(copy_sys_info->sib1 != NULL, "out of memory\n");
|
||||
memcpy(copy_sys_info->sib1, orig_sys_info->sib1, orig_sys_info->sib1_length);
|
||||
copy_sys_info->sib1_length = orig_sys_info->sib1_length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* transfer to RRC via ITTI */
|
||||
F1AP_GNB_DU_CONFIGURATION_UPDATE(msg) = cp_f1ap_du_configuration_update(upd);
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, 0, msg);
|
||||
}
|
||||
|
||||
@@ -277,20 +197,8 @@ static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const
|
||||
{
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE);
|
||||
msg->ittiMsgHeader.originInstance = -1; // means monolithic
|
||||
/* copy all fields, but reallocate rrc_containers! */
|
||||
f1ap_initial_ul_rrc_message_t *f1ap_msg = &F1AP_INITIAL_UL_RRC_MESSAGE(msg);
|
||||
*f1ap_msg = *ul_rrc;
|
||||
|
||||
f1ap_msg->rrc_container = malloc(ul_rrc->rrc_container_length);
|
||||
DevAssert(f1ap_msg->rrc_container);
|
||||
memcpy(f1ap_msg->rrc_container, ul_rrc->rrc_container, ul_rrc->rrc_container_length);
|
||||
f1ap_msg->rrc_container_length = ul_rrc->rrc_container_length;
|
||||
|
||||
f1ap_msg->du2cu_rrc_container = malloc(ul_rrc->du2cu_rrc_container_length);
|
||||
DevAssert(f1ap_msg->du2cu_rrc_container);
|
||||
memcpy(f1ap_msg->du2cu_rrc_container, ul_rrc->du2cu_rrc_container, ul_rrc->du2cu_rrc_container_length);
|
||||
f1ap_msg->du2cu_rrc_container_length = ul_rrc->du2cu_rrc_container_length;
|
||||
|
||||
*f1ap_msg = cp_initial_ul_rrc_message_transfer(ul_rrc);
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, module_id, msg);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,24 +29,23 @@
|
||||
|
||||
#include "mac_rrc_ul.h"
|
||||
|
||||
#include "f1ap_lib_extern.h"
|
||||
#include "lib/f1ap_interface_management.h"
|
||||
|
||||
static f1ap_net_config_t read_DU_IP_config(const eth_params_t* f1_params, const char *f1u_ip_addr)
|
||||
{
|
||||
f1ap_net_config_t nc = {0};
|
||||
|
||||
nc.CU_f1_ip_address.ipv6 = 0;
|
||||
nc.CU_f1_ip_address.ipv4 = 1;
|
||||
strcpy(nc.CU_f1_ip_address.ipv4_address, f1_params->remote_addr);
|
||||
nc.CU_f1_ip_address= strdup(f1_params->remote_addr);
|
||||
nc.CUport = f1_params->remote_portd;
|
||||
|
||||
nc.DU_f1c_ip_address.ipv6 = 0;
|
||||
nc.DU_f1c_ip_address.ipv4 = 1;
|
||||
strcpy(nc.DU_f1c_ip_address.ipv4_address, f1_params->my_addr);
|
||||
nc.DU_f1c_ip_address = strdup(f1_params->my_addr);
|
||||
nc.DU_f1u_ip_address = strdup(f1u_ip_addr);
|
||||
nc.DUport = f1_params->my_portd;
|
||||
LOG_I(F1AP,
|
||||
"F1-C DU IPaddr %s, connect to F1-C CU %s, binding GTP to %s\n",
|
||||
nc.DU_f1c_ip_address.ipv4_address,
|
||||
nc.CU_f1_ip_address.ipv4_address,
|
||||
nc.DU_f1c_ip_address,
|
||||
nc.CU_f1_ip_address,
|
||||
nc.DU_f1u_ip_address);
|
||||
|
||||
// sctp_in_streams/sctp_out_streams are given by SCTP layer
|
||||
@@ -70,84 +69,23 @@ static void f1_reset_acknowledge_cu_initiated_f1ap(const f1ap_reset_ack_t *ack)
|
||||
static void f1_setup_request_f1ap(const f1ap_setup_req_t *req)
|
||||
{
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_DU_REGISTER_REQ);
|
||||
|
||||
f1ap_setup_req_t *f1ap_setup = &F1AP_DU_REGISTER_REQ(msg).setup_req;
|
||||
f1ap_setup->gNB_DU_id = req->gNB_DU_id;
|
||||
f1ap_setup->gNB_DU_name = strdup(req->gNB_DU_name);
|
||||
f1ap_setup->num_cells_available = req->num_cells_available;
|
||||
for (int n = 0; n < req->num_cells_available; ++n) {
|
||||
f1ap_setup->cell[n].info = req->cell[n].info; // copy most fields
|
||||
if (req->cell[n].info.tac) {
|
||||
f1ap_setup->cell[n].info.tac = malloc(sizeof(*f1ap_setup->cell[n].info.tac));
|
||||
AssertFatal(f1ap_setup->cell[n].info.tac != NULL, "out of memory\n");
|
||||
*f1ap_setup->cell[n].info.tac = *req->cell[n].info.tac;
|
||||
}
|
||||
if (req->cell[n].info.measurement_timing_config_len > 0) {
|
||||
f1ap_setup->cell[n].info.measurement_timing_config = calloc(req->cell[n].info.measurement_timing_config_len, sizeof(uint8_t));
|
||||
AssertFatal(f1ap_setup->cell[n].info.measurement_timing_config != NULL, "out of memory\n");
|
||||
memcpy(f1ap_setup->cell[n].info.measurement_timing_config,
|
||||
req->cell[n].info.measurement_timing_config,
|
||||
req->cell[n].info.measurement_timing_config_len);
|
||||
f1ap_setup->cell[n].info.measurement_timing_config_len = req->cell[n].info.measurement_timing_config_len;
|
||||
}
|
||||
|
||||
if (req->cell[n].sys_info) {
|
||||
f1ap_gnb_du_system_info_t *orig_sys_info = req->cell[n].sys_info;
|
||||
f1ap_gnb_du_system_info_t *copy_sys_info = calloc(1, sizeof(*copy_sys_info));
|
||||
AssertFatal(copy_sys_info, "out of memory\n");
|
||||
f1ap_setup->cell[n].sys_info = copy_sys_info;
|
||||
|
||||
copy_sys_info->mib = calloc(orig_sys_info->mib_length, sizeof(uint8_t));
|
||||
AssertFatal(copy_sys_info->mib, "out of memory\n");
|
||||
memcpy(copy_sys_info->mib, orig_sys_info->mib, orig_sys_info->mib_length);
|
||||
copy_sys_info->mib_length = orig_sys_info->mib_length;
|
||||
|
||||
if (orig_sys_info->sib1_length > 0) {
|
||||
copy_sys_info->sib1 = calloc(orig_sys_info->sib1_length, sizeof(uint8_t));
|
||||
AssertFatal(copy_sys_info->sib1, "out of memory\n");
|
||||
memcpy(copy_sys_info->sib1, orig_sys_info->sib1, orig_sys_info->sib1_length);
|
||||
copy_sys_info->sib1_length = orig_sys_info->sib1_length;
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy(f1ap_setup->rrc_ver, req->rrc_ver, sizeof(req->rrc_ver));
|
||||
|
||||
f1ap_setup_req_t f1ap_setup = cp_f1ap_setup_request(req);
|
||||
F1AP_DU_REGISTER_REQ(msg).setup_req = f1ap_setup;
|
||||
F1AP_DU_REGISTER_REQ(msg).net_config = read_DU_IP_config(&RC.nrmac[0]->eth_params_n, RC.nrmac[0]->f1u_addr);
|
||||
|
||||
itti_send_msg_to_task(TASK_DU_F1, 0, msg);
|
||||
}
|
||||
|
||||
static void gnb_du_configuration_update_f1ap(const f1ap_gnb_du_configuration_update_t *upd)
|
||||
{
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_GNB_DU_CONFIGURATION_UPDATE);
|
||||
f1ap_gnb_du_configuration_update_t *f1_upd = &F1AP_GNB_DU_CONFIGURATION_UPDATE(msg);
|
||||
f1_upd->transaction_id = upd->transaction_id;
|
||||
AssertFatal(upd->num_cells_to_add == 0, "gNB-DU config update: cells to add not supported\n");
|
||||
f1_upd->num_cells_to_modify = upd->num_cells_to_modify;
|
||||
for (int n = 0; n < upd->num_cells_to_modify; ++n) {
|
||||
f1_upd->cell_to_modify[n].old_plmn = upd->cell_to_modify[n].old_plmn;
|
||||
f1_upd->cell_to_modify[n].old_nr_cellid = upd->cell_to_modify[n].old_nr_cellid;
|
||||
f1_upd->cell_to_modify[n].info = upd->cell_to_modify[n].info;
|
||||
if (upd->cell_to_modify[n].sys_info) {
|
||||
f1ap_gnb_du_system_info_t *orig_sys_info = upd->cell_to_modify[n].sys_info;
|
||||
f1ap_gnb_du_system_info_t *copy_sys_info = calloc(1, sizeof(*copy_sys_info));
|
||||
f1_upd->cell_to_modify[n].sys_info = copy_sys_info;
|
||||
|
||||
copy_sys_info->mib = calloc(orig_sys_info->mib_length, sizeof(uint8_t));
|
||||
AssertFatal(copy_sys_info->mib != NULL, "out of memory\n");
|
||||
memcpy(copy_sys_info->mib, orig_sys_info->mib, orig_sys_info->mib_length);
|
||||
copy_sys_info->mib_length = orig_sys_info->mib_length;
|
||||
|
||||
if (orig_sys_info->sib1_length > 0) {
|
||||
copy_sys_info->sib1 = calloc(orig_sys_info->sib1_length, sizeof(uint8_t));
|
||||
AssertFatal(copy_sys_info->sib1 != NULL, "out of memory\n");
|
||||
memcpy(copy_sys_info->sib1, orig_sys_info->sib1, orig_sys_info->sib1_length);
|
||||
copy_sys_info->sib1_length = orig_sys_info->sib1_length;
|
||||
}
|
||||
}
|
||||
}
|
||||
AssertFatal(upd->num_cells_to_delete == 0, "gNB-DU config update: cells to add not supported\n");
|
||||
itti_send_msg_to_task(TASK_DU_F1, 0, msg);
|
||||
/* copy F1AP message */
|
||||
f1ap_gnb_du_configuration_update_t cp = cp_f1ap_du_configuration_update(upd);
|
||||
/* transfer to ITTI message */
|
||||
F1AP_GNB_DU_CONFIGURATION_UPDATE(msg) = cp;
|
||||
/* free after copy */
|
||||
free_f1ap_du_configuration_update(upd);
|
||||
/* send to RRC task */
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, 0, msg);
|
||||
}
|
||||
|
||||
static void ue_context_setup_response_f1ap(const f1ap_ue_context_setup_t *req, const f1ap_ue_context_setup_t *resp)
|
||||
@@ -269,20 +207,8 @@ static void ue_context_release_complete_f1ap(const f1ap_ue_context_release_compl
|
||||
static void initial_ul_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc)
|
||||
{
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE);
|
||||
/* copy all fields, but reallocate rrc_containers! */
|
||||
f1ap_initial_ul_rrc_message_t *f1ap_msg = &F1AP_INITIAL_UL_RRC_MESSAGE(msg);
|
||||
*f1ap_msg = *ul_rrc;
|
||||
|
||||
f1ap_msg->rrc_container = malloc(ul_rrc->rrc_container_length);
|
||||
DevAssert(f1ap_msg->rrc_container);
|
||||
memcpy(f1ap_msg->rrc_container, ul_rrc->rrc_container, ul_rrc->rrc_container_length);
|
||||
f1ap_msg->rrc_container_length = ul_rrc->rrc_container_length;
|
||||
|
||||
f1ap_msg->du2cu_rrc_container = malloc(ul_rrc->du2cu_rrc_container_length);
|
||||
DevAssert(f1ap_msg->du2cu_rrc_container);
|
||||
memcpy(f1ap_msg->du2cu_rrc_container, ul_rrc->du2cu_rrc_container, ul_rrc->du2cu_rrc_container_length);
|
||||
f1ap_msg->du2cu_rrc_container_length = ul_rrc->du2cu_rrc_container_length;
|
||||
|
||||
*f1ap_msg = cp_initial_ul_rrc_message_transfer(ul_rrc);
|
||||
itti_send_msg_to_task(TASK_DU_F1, module_id, msg);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
|
||||
#include "mac_rrc_dl.h"
|
||||
#include "nr_rrc_defs.h"
|
||||
#include "openair2/F1AP/lib/f1ap_rrc_message_transfer.h"
|
||||
#include "openair2/F1AP/lib/f1ap_interface_management.h"
|
||||
|
||||
static void f1_reset_cu_initiated_f1ap(sctp_assoc_t assoc_id, const f1ap_reset_t *reset)
|
||||
{
|
||||
@@ -44,6 +46,7 @@ static void f1_setup_response_f1ap(sctp_assoc_t assoc_id, const f1ap_setup_resp_
|
||||
*f1ap_msg = *resp;
|
||||
if (resp->gNB_CU_name != NULL)
|
||||
f1ap_msg->gNB_CU_name = strdup(resp->gNB_CU_name);
|
||||
free_f1ap_setup_response(resp);
|
||||
itti_send_msg_to_task(TASK_CU_F1, 0, msg);
|
||||
}
|
||||
|
||||
@@ -210,18 +213,7 @@ static void dl_rrc_message_transfer_f1ap(sctp_assoc_t assoc_id, const f1ap_dl_rr
|
||||
MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_DL_RRC_MESSAGE);
|
||||
message_p->ittiMsgHeader.originInstance = assoc_id;
|
||||
f1ap_dl_rrc_message_t *msg = &F1AP_DL_RRC_MESSAGE(message_p);
|
||||
*msg = *dl_rrc;
|
||||
if (dl_rrc->old_gNB_DU_ue_id) {
|
||||
msg->old_gNB_DU_ue_id = malloc(sizeof(*msg->old_gNB_DU_ue_id));
|
||||
AssertFatal(msg->old_gNB_DU_ue_id != NULL, "out of memory\n");
|
||||
*msg->old_gNB_DU_ue_id = *dl_rrc->old_gNB_DU_ue_id;
|
||||
}
|
||||
if (dl_rrc->rrc_container) {
|
||||
msg->rrc_container = malloc(dl_rrc->rrc_container_length);
|
||||
AssertFatal(msg->rrc_container != NULL, "out of memory\n");
|
||||
msg->rrc_container_length = dl_rrc->rrc_container_length;
|
||||
memcpy(msg->rrc_container, dl_rrc->rrc_container, dl_rrc->rrc_container_length);
|
||||
}
|
||||
*msg = cp_dl_rrc_message_transfer(dl_rrc);
|
||||
itti_send_msg_to_task (TASK_CU_F1, 0, message_p);
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
#include <openair2/RRC/NR/nr_rrc_proto.h>
|
||||
#include "openair2/F1AP/f1ap_common.h"
|
||||
#include "openair2/F1AP/f1ap_ids.h"
|
||||
#include "openair2/F1AP/lib/f1ap_lib_extern.h"
|
||||
#include "openair2/SDAP/nr_sdap/nr_sdap_entity.h"
|
||||
#include "openair2/E1AP/e1ap.h"
|
||||
#include "cucp_cuup_if.h"
|
||||
@@ -1839,11 +1840,6 @@ void rrc_gNB_process_initial_ul_rrc_message(sctp_assoc_t assoc_id, const f1ap_in
|
||||
}
|
||||
}
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_UL_CCCH_Message, ul_ccch_msg);
|
||||
|
||||
if (ul_rrc->rrc_container)
|
||||
free(ul_rrc->rrc_container);
|
||||
if (ul_rrc->du2cu_rrc_container)
|
||||
free(ul_rrc->du2cu_rrc_container);
|
||||
}
|
||||
|
||||
void rrc_gNB_process_release_request(const module_id_t gnb_mod_idP, x2ap_ENDC_sgnb_release_request_t *m)
|
||||
@@ -2161,12 +2157,12 @@ static pdusession_level_qos_parameter_t *get_qos_characteristics(const int qfi,
|
||||
static f1ap_qos_characteristics_t get_qos_char_from_qos_flow_param(const pdusession_level_qos_parameter_t *qos_param)
|
||||
{
|
||||
f1ap_qos_characteristics_t qos_char = {0};
|
||||
if (qos_param->fiveQI_type == dynamic) {
|
||||
qos_char.qos_type = dynamic;
|
||||
if (qos_param->fiveQI_type == DYNAMIC) {
|
||||
qos_char.qos_type = DYNAMIC;
|
||||
qos_char.dynamic.fiveqi = qos_param->fiveQI;
|
||||
qos_char.dynamic.qos_priority_level = qos_param->qos_priority;
|
||||
} else {
|
||||
qos_char.qos_type = non_dynamic;
|
||||
qos_char.qos_type = NON_DYNAMIC;
|
||||
qos_char.non_dynamic.fiveqi = qos_param->fiveQI;
|
||||
qos_char.non_dynamic.qos_priority_level = qos_param->qos_priority;
|
||||
}
|
||||
@@ -2189,7 +2185,7 @@ static int fill_drb_to_be_setup_from_e1_resp(const gNB_RRC_INST *rrc,
|
||||
const DRB_nGRAN_setup_t *drb_config = &pduSession[p].DRBnGRanList[i];
|
||||
f1ap_drb_to_be_setup_t *drb = &drbs[nb_drb];
|
||||
drb->drb_id = pduSession[p].DRBnGRanList[i].id;
|
||||
drb->rlc_mode = rrc->configuration.um_on_default_drb ? RLC_MODE_UM : RLC_MODE_AM;
|
||||
drb->rlc_mode = rrc->configuration.um_on_default_drb ? F1AP_RLC_MODE_UM_BIDIR : F1AP_RLC_MODE_AM;
|
||||
drb->up_ul_tnl[0].tl_address = drb_config->UpParamList[0].tlAddress;
|
||||
drb->up_ul_tnl[0].port = rrc->eth_params_s.my_portd;
|
||||
drb->up_ul_tnl[0].teid = drb_config->UpParamList[0].teId;
|
||||
@@ -2439,6 +2435,7 @@ void *rrc_gnb_task(void *args_p) {
|
||||
AssertFatal(NODE_IS_CU(RC.nrrrc[instance]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[instance]->node_type),
|
||||
"should not receive F1AP_INITIAL_UL_RRC_MESSAGE, need call by CU!\n");
|
||||
rrc_gNB_process_initial_ul_rrc_message(msg_p->ittiMsgHeader.originInstance, &F1AP_INITIAL_UL_RRC_MESSAGE(msg_p));
|
||||
free_initial_ul_rrc_message_transfer(&F1AP_INITIAL_UL_RRC_MESSAGE(msg_p));
|
||||
break;
|
||||
|
||||
/* Messages from PDCP */
|
||||
@@ -2515,6 +2512,12 @@ void *rrc_gnb_task(void *args_p) {
|
||||
rrc_gNB_process_f1_du_configuration_update(&F1AP_GNB_DU_CONFIGURATION_UPDATE(msg_p), msg_p->ittiMsgHeader.originInstance);
|
||||
break;
|
||||
|
||||
case F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE:
|
||||
AssertFatal(!NODE_IS_DU(RC.nrrrc[instance]->node_type),
|
||||
"should not receive F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE in DU!\n");
|
||||
LOG_E(NR_RRC, "Handling of F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE not implemented\n");
|
||||
break;
|
||||
|
||||
/* Messages from X2AP */
|
||||
case X2AP_ENDC_SGNB_ADDITION_REQ:
|
||||
LOG_I(NR_RRC, "Received ENDC sgNB addition request from X2AP \n");
|
||||
|
||||
@@ -248,11 +248,11 @@ static void fill_qos(NGAP_QosFlowSetupRequestList_t *qos, pdusession_t *session)
|
||||
AssertFatal(qosChar, "Qos characteristics are not available for qos flow index %d\n", qosIdx);
|
||||
if (qosChar->present == NGAP_QosCharacteristics_PR_nonDynamic5QI) {
|
||||
AssertFatal(qosChar->choice.dynamic5QI, "Non-Dynamic 5QI is NULL\n");
|
||||
session->qos[qosIdx].fiveQI_type = non_dynamic;
|
||||
session->qos[qosIdx].fiveQI_type = NON_DYNAMIC;
|
||||
session->qos[qosIdx].fiveQI = (uint64_t)qosChar->choice.nonDynamic5QI->fiveQI;
|
||||
} else {
|
||||
AssertFatal(qosChar->choice.dynamic5QI, "Dynamic 5QI is NULL\n");
|
||||
session->qos[qosIdx].fiveQI_type = dynamic;
|
||||
session->qos[qosIdx].fiveQI_type = DYNAMIC;
|
||||
session->qos[qosIdx].fiveQI = (uint64_t)(*qosChar->choice.dynamic5QI->fiveQI);
|
||||
}
|
||||
|
||||
@@ -412,7 +412,7 @@ void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession
|
||||
qos_characteristics_t *qos_char = &qos_flow->qos_params.qos_characteristics;
|
||||
qos_flow->qfi = qos_session->qfi;
|
||||
qos_char->qos_type = qos_session->fiveQI_type;
|
||||
if (qos_char->qos_type == dynamic) {
|
||||
if (qos_char->qos_type == DYNAMIC) {
|
||||
qos_char->dynamic.fiveqi = qos_session->fiveQI;
|
||||
qos_char->dynamic.qos_priority_level = qos_session->qos_priority;
|
||||
} else {
|
||||
@@ -861,11 +861,11 @@ static void fill_qos2(NGAP_QosFlowAddOrModifyRequestList_t *qos, pdusession_t *s
|
||||
AssertFatal(qosChar, "Qos characteristics are not available for qos flow index %d\n", qosIdx);
|
||||
if (qosChar->present == NGAP_QosCharacteristics_PR_nonDynamic5QI) {
|
||||
AssertFatal(qosChar->choice.dynamic5QI, "Non-Dynamic 5QI is NULL\n");
|
||||
session->qos[qosIdx].fiveQI_type = non_dynamic;
|
||||
session->qos[qosIdx].fiveQI_type = NON_DYNAMIC;
|
||||
session->qos[qosIdx].fiveQI = (uint64_t)qosChar->choice.nonDynamic5QI->fiveQI;
|
||||
} else {
|
||||
AssertFatal(qosChar->choice.dynamic5QI, "Dynamic 5QI is NULL\n");
|
||||
session->qos[qosIdx].fiveQI_type = dynamic;
|
||||
session->qos[qosIdx].fiveQI_type = DYNAMIC;
|
||||
session->qos[qosIdx].fiveQI = (uint64_t)(*qosChar->choice.dynamic5QI->fiveQI);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "common/utils/ds/seq_arr.h"
|
||||
#include "common/utils/alg/foreach.h"
|
||||
#include "lib/f1ap_interface_management.h"
|
||||
|
||||
int get_dl_band(const struct f1ap_served_cell_info_t *cell_info)
|
||||
{
|
||||
@@ -261,6 +262,8 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
|
||||
DevAssert(rrc);
|
||||
|
||||
LOG_I(NR_RRC, "Received F1 Setup Request from gNB_DU %lu (%s) on assoc_id %d\n", req->gNB_DU_id, req->gNB_DU_name, assoc_id);
|
||||
// pre-fill F1 Setup Failure message
|
||||
f1ap_setup_failure_t fail = {.transaction_id = F1AP_get_next_transaction_identifier(0, 0)};
|
||||
|
||||
// check:
|
||||
// - it is one cell
|
||||
@@ -269,7 +272,7 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
|
||||
// else reject
|
||||
if (req->num_cells_available != 1) {
|
||||
LOG_E(NR_RRC, "can only handle on DU cell, but gNB_DU %ld has %d\n", req->gNB_DU_id, req->num_cells_available);
|
||||
f1ap_setup_failure_t fail = {.cause = F1AP_CauseRadioNetwork_gNB_CU_Cell_Capacity_Exceeded};
|
||||
fail.cause = F1AP_CauseRadioNetwork_gNB_CU_Cell_Capacity_Exceeded;
|
||||
rrc->mac_rrc.f1_setup_failure(assoc_id, &fail);
|
||||
return;
|
||||
}
|
||||
@@ -283,7 +286,7 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
|
||||
cell_info->plmn.mcc,
|
||||
cell_info->plmn.mnc_digit_length,
|
||||
cell_info->plmn.mnc);
|
||||
f1ap_setup_failure_t fail = {.cause = F1AP_CauseRadioNetwork_plmn_not_served_by_the_gNB_CU};
|
||||
fail.cause = F1AP_CauseRadioNetwork_plmn_not_served_by_the_gNB_CU;
|
||||
rrc->mac_rrc.f1_setup_failure(assoc_id, &fail);
|
||||
return;
|
||||
}
|
||||
@@ -295,7 +298,7 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
|
||||
it->setup_req->gNB_DU_name,
|
||||
it->assoc_id,
|
||||
it->setup_req->gNB_DU_id);
|
||||
f1ap_setup_failure_t fail = {.cause = F1AP_CauseMisc_unspecified};
|
||||
fail.cause = F1AP_CauseMisc_unspecified;
|
||||
rrc->mac_rrc.f1_setup_failure(assoc_id, &fail);
|
||||
return;
|
||||
}
|
||||
@@ -312,7 +315,7 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
|
||||
exist_info->nr_pci,
|
||||
new_info->nr_cellid,
|
||||
new_info->nr_pci);
|
||||
f1ap_setup_failure_t fail = {.cause = F1AP_CauseMisc_unspecified};
|
||||
fail.cause = F1AP_CauseMisc_unspecified;
|
||||
rrc->mac_rrc.f1_setup_failure(assoc_id, &fail);
|
||||
return;
|
||||
}
|
||||
@@ -339,7 +342,7 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
|
||||
if (sys_info != NULL && sys_info->mib != NULL && !(sys_info->sib1 == NULL && get_softmodem_params()->sa)) {
|
||||
if (!extract_sys_info(sys_info, &mib, &sib1)) {
|
||||
LOG_W(RRC, "rejecting DU ID %ld\n", req->gNB_DU_id);
|
||||
f1ap_setup_failure_t fail = {.cause = F1AP_CauseProtocol_semantic_error};
|
||||
fail.cause = F1AP_CauseProtocol_semantic_error;
|
||||
rrc->mac_rrc.f1_setup_failure(assoc_id, &fail);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_MeasurementTimingConfiguration, mtc);
|
||||
return;
|
||||
@@ -358,7 +361,8 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
|
||||
* allocate memory and copy it in */
|
||||
du->setup_req = calloc(1,sizeof(*du->setup_req));
|
||||
AssertFatal(du->setup_req, "out of memory\n");
|
||||
*du->setup_req = *req;
|
||||
// Copy F1AP message
|
||||
*du->setup_req = cp_f1ap_setup_request(req);
|
||||
// MIB can be null and configured later via DU Configuration Update
|
||||
du->mib = mib;
|
||||
du->sib1 = sib1;
|
||||
@@ -379,6 +383,8 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
|
||||
f1ap_setup_resp_t resp = {.transaction_id = req->transaction_id,
|
||||
.num_cells_to_activate = 1,
|
||||
.cells_to_activate[0] = cell};
|
||||
// free F1AP message after use
|
||||
free_f1ap_setup_request(req);
|
||||
int num = read_version(TO_STRING(NR_RRC_VERSION), &resp.rrc_ver[0], &resp.rrc_ver[1], &resp.rrc_ver[2]);
|
||||
AssertFatal(num == 3, "could not read RRC version string %s\n", TO_STRING(NR_RRC_VERSION));
|
||||
if (rrc->node_name != NULL)
|
||||
@@ -510,8 +516,9 @@ void rrc_gNB_process_f1_du_configuration_update(f1ap_gnb_du_configuration_update
|
||||
|
||||
/* Send DU Configuration Acknowledgement */
|
||||
f1ap_gnb_du_configuration_update_acknowledge_t ack = {.transaction_id = conf_up->transaction_id};
|
||||
|
||||
rrc->mac_rrc.gnb_du_configuration_update_acknowledge(assoc_id, &ack);
|
||||
/* free F1AP message after use */
|
||||
free_f1ap_du_configuration_update(conf_up);
|
||||
}
|
||||
|
||||
void rrc_CU_process_f1_lost_connection(gNB_RRC_INST *rrc, f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id)
|
||||
|
||||
Reference in New Issue
Block a user