mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 12:40:28 +00:00
Compare commits
8 Commits
develop
...
xnho_sree_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9588a8ebca | ||
|
|
3dfe1f6e77 | ||
|
|
5f7e568529 | ||
|
|
ceaddf9e27 | ||
|
|
a53a73c744 | ||
|
|
f593083983 | ||
|
|
431d72de83 | ||
|
|
9f092d0061 |
@@ -1458,7 +1458,7 @@ add_library(e1_if
|
||||
|
||||
target_link_libraries(e1_if PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs asn1_f1ap SECURITY ${OPENSSL_LIBRARIES} e1ap GTPV1U)
|
||||
|
||||
target_link_libraries(L2_NR PRIVATE f1ap x2ap s1ap ngap nr_rrc e1ap nr_rlc)
|
||||
target_link_libraries(L2_NR PRIVATE f1ap x2ap s1ap ngap nr_rrc e1ap nr_rlc xnap)
|
||||
if(E2_AGENT)
|
||||
target_link_libraries(L2_NR PUBLIC e2_agent e2_ran_func)
|
||||
target_compile_definitions(L2_NR PRIVATE ${E2AP_VERSION} ${KPM_VERSION})
|
||||
|
||||
@@ -213,6 +213,7 @@ typedef enum {
|
||||
LOCALIZE,
|
||||
F1U,
|
||||
X2AP,
|
||||
XNAP,
|
||||
M2AP,
|
||||
M3AP,
|
||||
NGAP,
|
||||
|
||||
@@ -466,6 +466,27 @@ ID = LEGACY_X2AP_TRACE
|
||||
GROUP = ALL:LEGACY_X2AP:LEGACY_GROUP_TRACE:LEGACY
|
||||
FORMAT = string,log
|
||||
|
||||
ID = LEGACY_XNAP_INFO
|
||||
DESC = XNAP legacy logs - info level
|
||||
GROUP = ALL:LEGACY_XNAP:LEGACY_GROUP_INFO:LEGACY
|
||||
FORMAT = string,log
|
||||
ID = LEGACY_XNAP_ERROR
|
||||
DESC = XNAP legacy logs - error level
|
||||
GROUP = ALL:LEGACY_XNAP:LEGACY_GROUP_ERROR:LEGACY
|
||||
FORMAT = string,log
|
||||
ID = LEGACY_XNAP_WARNING
|
||||
DESC = XNAP legacy logs - warning level
|
||||
GROUP = ALL:LEGACY_XNAP:LEGACY_GROUP_WARNING:LEGACY
|
||||
FORMAT = string,log
|
||||
ID = LEGACY_XNAP_DEBUG
|
||||
DESC = XNAP legacy logs - debug level
|
||||
GROUP = ALL:LEGACY_XNAP:LEGACY_GROUP_DEBUG:LEGACY
|
||||
FORMAT = string,log
|
||||
ID = LEGACY_XNAP_TRACE
|
||||
DESC = XNAP legacy logs - trace level
|
||||
GROUP = ALL:LEGACY_XNAP:LEGACY_GROUP_TRACE:LEGACY
|
||||
FORMAT = string,log
|
||||
|
||||
ID = LEGACY_M2AP_INFO
|
||||
DESC = M2AP legacy logs - info level
|
||||
GROUP = ALL:LEGACY_M2AP:LEGACY_GROUP_INFO:LEGACY
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#endif
|
||||
#include "openair2/COMMON/s1ap_messages_def.h"
|
||||
#include "openair2/COMMON/x2ap_messages_def.h"
|
||||
#include "openair2/COMMON/xnap_messages_def.h"
|
||||
#include "openair2/COMMON/m2ap_messages_def.h"
|
||||
#include "openair2/COMMON/m3ap_messages_def.h"
|
||||
#include "openair2/COMMON/sctp_messages_def.h"
|
||||
|
||||
@@ -227,6 +227,7 @@ typedef struct IttiMsgText_s {
|
||||
#endif
|
||||
#include <openair2/COMMON/s1ap_messages_types.h>
|
||||
#include <openair2/COMMON/x2ap_messages_types.h>
|
||||
#include <openair2/COMMON/xnap_messages_types.h>
|
||||
#include <openair2/COMMON/m2ap_messages_types.h>
|
||||
#include <openair2/COMMON/m3ap_messages_types.h>
|
||||
#include <openair2/COMMON/sctp_messages_types.h>
|
||||
@@ -298,6 +299,7 @@ typedef struct {
|
||||
TASK_DEF(TASK_S1AP, 200) \
|
||||
TASK_DEF(TASK_NGAP, 200) \
|
||||
TASK_DEF(TASK_X2AP, 200) \
|
||||
TASK_DEF(TASK_XNAP, 200) \
|
||||
TASK_DEF(TASK_M2AP_ENB, 200) \
|
||||
TASK_DEF(TASK_M2AP_MCE, 200) \
|
||||
TASK_DEF(TASK_M3AP, 200) \
|
||||
|
||||
@@ -74,6 +74,7 @@ unsigned short config_frames[4] = {2,9,11,13};
|
||||
#include "executables/thread-common.h"
|
||||
#include "NB_IoT_interface.h"
|
||||
#include "x2ap_eNB.h"
|
||||
#include "openair2/XNAP/xnap_gNB_task.h"
|
||||
#include "ngap_gNB.h"
|
||||
#include "gnb_paramdef.h"
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
@@ -356,6 +357,14 @@ static int create_gNB_tasks(ngran_node_t node_type, configmodule_interface_t *cf
|
||||
} else {
|
||||
LOG_I(X2AP, "X2AP is disabled.\n");
|
||||
}
|
||||
|
||||
if (is_xnap_enabled()) {
|
||||
if (itti_create_task(TASK_XNAP, xnap_task, NULL) < 0) {
|
||||
LOG_E(XNAP, "Create task for XNAP failed\n");
|
||||
}
|
||||
} else {
|
||||
LOG_I(XNAP, "XNAP is disabled.\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (get_softmodem_params()->sa &&
|
||||
|
||||
@@ -174,6 +174,7 @@ typedef struct ngap_security_capabilities_s {
|
||||
uint16_t nRintegrity_algorithms;
|
||||
uint16_t eUTRAencryption_algorithms;
|
||||
uint16_t eUTRAintegrity_algorithms;
|
||||
uint16_t encryption_algorithms;
|
||||
} ngap_security_capabilities_t;
|
||||
|
||||
/* Provides the establishment cause for the RRC connection request as provided
|
||||
|
||||
@@ -411,7 +411,8 @@ typedef struct NRRrcConfigurationReq_s {
|
||||
uint16_t mnc[PLMN_LIST_MAX_SIZE];
|
||||
uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE];
|
||||
uint8_t num_plmn;
|
||||
|
||||
NR_ServingCellConfigCommon_t *serving_cell_config_common; //imran
|
||||
NR_ServingCellConfig_t *serving_cell_config;
|
||||
bool um_on_default_drb;
|
||||
bool enable_sdap;
|
||||
int drbs;
|
||||
|
||||
36
openair2/COMMON/xnap_messages_def.h
Normal file
36
openair2/COMMON/xnap_messages_def.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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 xnap_messages_def.h
|
||||
* \author Sreeshma Shiv <sreeshmau@iisc.ac.in>
|
||||
* \date August 2023
|
||||
* \version 1.0
|
||||
*/
|
||||
|
||||
/* gNB application layer -> XNAP messages */
|
||||
MESSAGE_DEF(XNAP_REGISTER_GNB_REQ, MESSAGE_PRIORITY_MED, xnap_register_gnb_req_t, xnap_register_gnb_req)
|
||||
/* XNAP -> gNB application layer messages */
|
||||
|
||||
/* handover messages XNAP <-> RRC */
|
||||
MESSAGE_DEF(XNAP_SETUP_REQ, MESSAGE_PRIORITY_MED, xnap_setup_req_t, xnap_setup_req)
|
||||
MESSAGE_DEF(XNAP_SETUP_RESP, MESSAGE_PRIORITY_MED, xnap_setup_resp_t, xnap_setup_resp)
|
||||
MESSAGE_DEF(XNAP_SETUP_FAILURE, MESSAGE_PRIORITY_MED, xnap_setup_failure_t, xnap_setup_failure)
|
||||
MESSAGE_DEF(XNAP_HANDOVER_REQ, MESSAGE_PRIORITY_MED, xnap_handover_req_t, xnap_handover_req)
|
||||
286
openair2/COMMON/xnap_messages_types.h
Normal file
286
openair2/COMMON/xnap_messages_types.h
Normal file
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* 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 xnap_messages_types.h
|
||||
* \author Sreeshma Shiv <sreeshmau@iisc.ac.in>
|
||||
* \date August 2023
|
||||
* \version 1.0
|
||||
*/
|
||||
#ifndef XNAP_MESSAGES_TYPES_H_
|
||||
#define XNAP_MESSAGES_TYPES_H_
|
||||
|
||||
#include "s1ap_messages_types.h"
|
||||
#include "f1ap_messages_types.h"
|
||||
|
||||
#define XNAP_REGISTER_GNB_REQ(mSGpTR) (mSGpTR)->ittiMsg.xnap_register_gnb_req
|
||||
#define XNAP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.xnap_setup_req
|
||||
#define XNAP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.xnap_setup_resp
|
||||
#define XNAP_SETUP_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.xnap_setup_failure
|
||||
#define XNAP_HANDOVER_REQ(mSGpTR) (mSGpTR)->ittiMsg.xnap_handover_req
|
||||
|
||||
#define XNAP_MAX_NB_GNB_IP_ADDRESS 4
|
||||
|
||||
// gNB application layer -> XNAP messages
|
||||
|
||||
typedef struct xnap_net_ip_address_s {
|
||||
unsigned ipv4:1;
|
||||
unsigned ipv6:1;
|
||||
char ipv4_address[16];
|
||||
char ipv6_address[46];
|
||||
} xnap_net_ip_address_t;
|
||||
|
||||
typedef struct xnap_sctp_s {
|
||||
uint16_t sctp_in_streams;
|
||||
uint16_t sctp_out_streams;
|
||||
} xnap_sctp_t;
|
||||
|
||||
typedef struct xnap_net_config_t {
|
||||
uint8_t nb_xn;
|
||||
xnap_net_ip_address_t gnb_xn_ip_address;
|
||||
xnap_net_ip_address_t target_gnb_xn_ip_address[XNAP_MAX_NB_GNB_IP_ADDRESS];
|
||||
uint32_t gnb_port_for_XNC;
|
||||
xnap_sctp_t sctp_streams;
|
||||
} xnap_net_config_t;
|
||||
|
||||
typedef struct xnap_plmn_t {
|
||||
uint16_t mcc;
|
||||
uint16_t mnc;
|
||||
uint8_t mnc_digit_length;
|
||||
} xnap_plmn_t;
|
||||
|
||||
typedef struct xnap_amf_regioninfo_s {
|
||||
uint16_t mcc;
|
||||
uint16_t mnc;
|
||||
uint8_t mnc_len;
|
||||
uint8_t amf_region_id;
|
||||
} xnap_amf_regioninfo_t;
|
||||
|
||||
typedef enum xnap_mode_t { XNAP_MODE_TDD = 0, XNAP_MODE_FDD = 1 } xnap_mode_t;
|
||||
|
||||
typedef struct xnap_nr_frequency_info_t {
|
||||
uint32_t arfcn;
|
||||
int band;
|
||||
} xnap_nr_frequency_info_t;
|
||||
|
||||
typedef struct xnap_transmission_bandwidth_t {
|
||||
uint8_t scs;
|
||||
uint16_t nrb;
|
||||
} xnap_transmission_bandwidth_t;
|
||||
|
||||
typedef struct xnap_fdd_info_t {
|
||||
xnap_nr_frequency_info_t ul_freqinfo;
|
||||
xnap_nr_frequency_info_t dl_freqinfo;
|
||||
xnap_transmission_bandwidth_t ul_tbw;
|
||||
xnap_transmission_bandwidth_t dl_tbw;
|
||||
} xnap_fdd_info_t;
|
||||
|
||||
typedef struct xnap_tdd_info_t {
|
||||
xnap_nr_frequency_info_t freqinfo;
|
||||
xnap_transmission_bandwidth_t tbw;
|
||||
} xnap_tdd_info_t;
|
||||
|
||||
typedef struct xnap_snssai_s {
|
||||
uint8_t sst;
|
||||
uint8_t sd;
|
||||
} xnap_snssai_t;
|
||||
|
||||
typedef struct xnap_served_cell_info_t {
|
||||
// NR CGI
|
||||
xnap_plmn_t plmn;
|
||||
uint64_t nr_cellid; // NR Global Cell Id
|
||||
uint16_t nr_pci;// NR Physical Cell Ids
|
||||
|
||||
/* Tracking area code */
|
||||
uint32_t tac;
|
||||
|
||||
xnap_mode_t mode;
|
||||
union {
|
||||
xnap_fdd_info_t fdd;
|
||||
xnap_tdd_info_t tdd;
|
||||
};
|
||||
|
||||
char *measurement_timing_information;
|
||||
} xnap_served_cell_info_t;
|
||||
|
||||
typedef struct xnap_setup_req_s {
|
||||
uint64_t gNB_id;
|
||||
/* Tracking area code */
|
||||
uint16_t num_tai;
|
||||
uint32_t tai_support;
|
||||
xnap_plmn_t plmn_support;
|
||||
// Number of slide support items
|
||||
uint16_t num_snssai;
|
||||
xnap_snssai_t snssai[2];
|
||||
xnap_amf_regioninfo_t amf_region_info;
|
||||
uint8_t num_cells_available;
|
||||
xnap_served_cell_info_t info;
|
||||
} xnap_setup_req_t;
|
||||
|
||||
typedef struct xnap_setup_resp_s {
|
||||
int64_t gNB_id;
|
||||
/* Tracking area code */
|
||||
uint16_t num_tai;
|
||||
uint32_t tai_support;
|
||||
xnap_plmn_t plmn_support;
|
||||
// Number of slide support items
|
||||
uint16_t num_ssi;
|
||||
uint8_t sst;
|
||||
uint8_t sd;
|
||||
uint16_t nb_xn;//number of gNBs connected
|
||||
xnap_served_cell_info_t info;
|
||||
} xnap_setup_resp_t;
|
||||
|
||||
typedef struct xnap_register_gnb_req_s {
|
||||
xnap_setup_req_t setup_req;
|
||||
xnap_net_config_t net_config;
|
||||
char *gNB_name;
|
||||
} xnap_register_gnb_req_t;
|
||||
|
||||
typedef enum xnap_Cause_e {
|
||||
XNAP_CAUSE_NOTHING, /* No components present */
|
||||
XNAP_CAUSE_RADIO_NETWORK,
|
||||
XNAP_CAUSE_TRANSPORT,
|
||||
XNAP_CAUSE_PROTOCOL,
|
||||
XNAP_CAUSE_MISC,
|
||||
} xnap_Cause_t;
|
||||
|
||||
typedef struct xnap_setup_failure_s {
|
||||
long cause_value;
|
||||
xnap_Cause_t cause_type;
|
||||
uint16_t time_to_wait;
|
||||
uint16_t criticality_diagnostics;
|
||||
} xnap_setup_failure_t;
|
||||
|
||||
typedef struct xnap_guami_s {
|
||||
xnap_plmn_t plmn_id;
|
||||
uint8_t amf_region_id;
|
||||
uint8_t amf_set_id;
|
||||
uint8_t amf_pointer;
|
||||
} xnap_guami_t;
|
||||
|
||||
typedef struct xnap_allocation_retention_priority_s {
|
||||
uint16_t priority_level;
|
||||
preemption_capability_t preemption_capability;
|
||||
preemption_vulnerability_t preemption_vulnerability;
|
||||
} xnap_allocation_retention_priority_t;
|
||||
|
||||
typedef struct xnap_qos_characteristics_s {
|
||||
union {
|
||||
struct {
|
||||
long fiveqi;
|
||||
long qos_priority_level;
|
||||
} non_dynamic;
|
||||
struct {
|
||||
long fiveqi; // -1 -> optional
|
||||
long qos_priority_level;
|
||||
long packet_delay_budget;
|
||||
struct {
|
||||
long per_scalar;
|
||||
long per_exponent;
|
||||
} packet_error_rate;
|
||||
} dynamic;
|
||||
};
|
||||
fiveQI_type_t qos_type;
|
||||
} xnap_qos_characteristics_t;
|
||||
|
||||
typedef struct xnap_qos_tobe_setup_item_s {
|
||||
uint8_t qfi;
|
||||
xnap_qos_characteristics_t qos_params;
|
||||
xnap_allocation_retention_priority_t allocation_retention_priority;
|
||||
} xnap_qos_tobe_setup_item_t;
|
||||
|
||||
typedef struct xnap_qos_tobe_setup_list_s {
|
||||
uint8_t num_qos;
|
||||
xnap_qos_tobe_setup_item_t qos[2]; //QOSFLOW_MAX_VALUE= 64 Put this?
|
||||
} xnap_qos_tobe_setup_list_t;
|
||||
|
||||
typedef struct xnap_pdusession_tobe_setup_item_s {
|
||||
uint8_t pdusession_id;
|
||||
xnap_snssai_t snssai;
|
||||
xnap_net_ip_address_t up_ngu_tnl_ip_upf;
|
||||
teid_t up_ngu_tnl_teid_upf;
|
||||
uint32_t pdu_session_type; //enumerated-pdu_session_type_t- ngap_messages_types.h
|
||||
xnap_qos_tobe_setup_list_t qos_list;
|
||||
} xnap_pdusession_tobe_setup_item_t;
|
||||
|
||||
typedef struct xnap_pdusession_tobe_setup_list_s {
|
||||
uint8_t num_pdu;
|
||||
xnap_pdusession_tobe_setup_item_t pdu[NGAP_MAX_PDUSESSION]; //Is the limit ok?
|
||||
} xnap_pdusession_tobe_setup_list_t;
|
||||
|
||||
typedef struct xnap_ngran_cgi_t {
|
||||
xnap_plmn_t plmn_id;
|
||||
uint32_t cgi;
|
||||
} xnap_ngran_cgi_t;
|
||||
|
||||
typedef struct xnap_security_capabilities_s {
|
||||
uint16_t encryption_algorithms;
|
||||
uint16_t integrity_algorithms;
|
||||
} xnap_security_capabilities_t;
|
||||
|
||||
typedef struct xnap_ambr_s {
|
||||
uint64_t br_ul;
|
||||
uint64_t br_dl;
|
||||
} xnap_ambr_t;
|
||||
|
||||
typedef struct xnap_uehistory_info_s {
|
||||
xnap_ngran_cgi_t last_visited_cgi;
|
||||
cell_type_t cell_type; //enumerated -s1ap_messages_types.h
|
||||
uint64_t time_UE_StayedInCell;
|
||||
} xnap_uehistory_info_t; //38.413- 9.3.1.97
|
||||
|
||||
typedef struct xnap_ue_context_info_s {
|
||||
uint64_t ngc_ue_sig_ref;// 0-2^40-1
|
||||
xnap_net_ip_address_t tnl_ip_source;
|
||||
uint32_t tnl_port_source;
|
||||
xnap_security_capabilities_t security_capabilities;
|
||||
uint8_t kRRCenc[16];
|
||||
uint8_t kRRCint[16];
|
||||
uint8_t as_security_key_ranstar[32];//bitstring 256, why array?
|
||||
uint32_t as_security_ncc;
|
||||
xnap_ambr_t ue_ambr;
|
||||
uint8_t rrc_buffer[8192 /* arbitrary, big enough */];
|
||||
xnap_pdusession_tobe_setup_list_t pdusession_tobe_setup_list;
|
||||
xnap_uehistory_info_t uehistory_info;//most recent info added at top(upto 16). how many needed?
|
||||
int rrc_buffer_size;//rrc msg type needed?
|
||||
int target_assoc_id;
|
||||
uint8_t nb_e_rabs_tobesetup;
|
||||
} xnap_ue_context_info_t;
|
||||
|
||||
typedef struct xnap_handover_req_s {
|
||||
uint32_t ng_node_ue_xnap_id;
|
||||
xnap_plmn_t plmn_id;
|
||||
xnap_Cause_t cause_type;
|
||||
xnap_ngran_cgi_t target_cgi;
|
||||
xnap_guami_t guami;
|
||||
xnap_ue_context_info_t ue_context;
|
||||
} xnap_handover_req_t;
|
||||
|
||||
typedef struct xnap_handover_req_ack_s {
|
||||
uint32_t ng_node_ue_xnap_id;
|
||||
xnap_Cause_t cause_type;
|
||||
xnap_ngran_cgi_t target_cgi;
|
||||
xnap_guami_t guami;
|
||||
xnap_ue_context_info_t ue_context;
|
||||
} xnap_handover_req_ack_t;
|
||||
|
||||
#endif /* XNAP_MESSAGES_TYPES_H_ */
|
||||
|
||||
@@ -68,7 +68,7 @@ static void get_NGU_S1U_addr(char **addr, uint16_t *port)
|
||||
return;
|
||||
}
|
||||
|
||||
MessageDef *RCconfig_NR_CU_E1(const E1_t *entity)
|
||||
MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process)
|
||||
{
|
||||
MessageDef *msgConfig = itti_alloc_new_message(TASK_GNB_APP, 0, E1AP_REGISTER_REQ);
|
||||
if (!msgConfig)
|
||||
@@ -82,12 +82,14 @@ MessageDef *RCconfig_NR_CU_E1(const E1_t *entity)
|
||||
sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0);
|
||||
int num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt;
|
||||
AssertFatal(num_gnbs == 1, "Support only one gNB per process\n");
|
||||
config_getlist(config_get_if(), &GNBParamList, GNBParams, sizeofArray(GNBParams), NULL);
|
||||
paramdef_t *gnbParms = GNBParamList.paramarray[0];
|
||||
e1ap_setup_req_t *e1Setup = &E1AP_REGISTER_REQ(msgConfig).setup_req;
|
||||
|
||||
if (num_gnbs > 0) {
|
||||
config_getlist(config_get_if(), &GNBParamList, GNBParams, sizeofArray(GNBParams), NULL);
|
||||
paramdef_t *gnbParms = GNBParamList.paramarray[0];
|
||||
AssertFatal(gnbParms[GNB_GNB_ID_IDX].uptr != NULL, "gNB id %d is not defined in configuration file\n", 0);
|
||||
e1ap_setup_req_t *e1Setup = &E1AP_REGISTER_REQ(msgConfig).setup_req;
|
||||
msgConfig->ittiMsgHeader.destinationInstance = 0;
|
||||
e1Setup->gNB_cu_up_id = *(gnbParms[GNB_GNB_ID_IDX].uptr);
|
||||
if (*gnbParms[GNB_GNB_NAME_IDX].strptr)
|
||||
e1Setup->gNB_cu_up_name = *(gnbParms[GNB_GNB_NAME_IDX].strptr);
|
||||
|
||||
@@ -130,11 +132,7 @@ MessageDef *RCconfig_NR_CU_E1(const E1_t *entity)
|
||||
get_NGU_S1U_addr(&e1ap_nc->localAddressN3, &e1ap_nc->localPortN3);
|
||||
e1ap_nc->remotePortN3 = e1ap_nc->localPortN3 ;
|
||||
|
||||
AssertFatal(config_isparamset(gnbParms, GNB_GNB_ID_IDX), "%s is not defined in configuration file\n", GNB_CONFIG_STRING_GNB_ID);
|
||||
uint32_t gnb_id = *gnbParms[GNB_GNB_ID_IDX].uptr;
|
||||
E1AP_REGISTER_REQ(msgConfig).gnb_id = gnb_id;
|
||||
|
||||
if (entity != NULL) {
|
||||
if (separate_CUUP_process) {
|
||||
paramlist_def_t GNBE1ParamList = {GNB_CONFIG_STRING_E1_PARAMETERS, NULL, 0};
|
||||
paramdef_t GNBE1Params[] = GNBE1PARAMS_DESC;
|
||||
config_getlist(config_get_if(), &GNBE1ParamList, GNBE1Params, sizeofArray(GNBE1Params), aprefix);
|
||||
@@ -143,24 +141,6 @@ MessageDef *RCconfig_NR_CU_E1(const E1_t *entity)
|
||||
e1ap_nc->CUCP_e1_ip_address.ipv4 = 1;
|
||||
strcpy(e1ap_nc->CUUP_e1_ip_address.ipv4_address, *(e1Parms[GNB_CONFIG_E1_IPV4_ADDRESS_CUUP].strptr));
|
||||
e1ap_nc->CUUP_e1_ip_address.ipv4 = 1;
|
||||
if (*entity == CPtype) {
|
||||
// CP needs gNB_ID (although not used, but other parts check it as
|
||||
// well), and gNB-CU-UP ID should NOT be present as it comes through E1!
|
||||
AssertFatal(!config_isparamset(gnbParms, GNB_GNB_CU_UP_ID_IDX), "%s must not be defined in configuration file\n", GNB_CONFIG_STRING_GNB_CU_UP_ID);
|
||||
} else { // UPtype
|
||||
AssertFatal(config_isparamset(gnbParms, GNB_GNB_CU_UP_ID_IDX), "%s is not be defined in configuration file\n", GNB_CONFIG_STRING_GNB_CU_UP_ID);
|
||||
e1Setup->gNB_cu_up_id = *gnbParms[GNB_GNB_CU_UP_ID_IDX].u64ptr;
|
||||
}
|
||||
} else {
|
||||
// integrated CU-CP/UP. We don't care about the gNB-CU-UP ID that much,
|
||||
// but if it's there, check it's the same as gNB ID
|
||||
uint64_t *gnb_cu_up_id = gnbParms[GNB_GNB_CU_UP_ID_IDX].u64ptr;
|
||||
AssertFatal(!config_isparamset(gnbParms, GNB_GNB_CU_UP_ID_IDX) || *gnb_cu_up_id == gnb_id,
|
||||
"%s is different of %s: they need to match or remove %s from config\n",
|
||||
GNB_CONFIG_STRING_GNB_CU_UP_ID,
|
||||
GNB_CONFIG_STRING_GNB_ID,
|
||||
GNB_CONFIG_STRING_GNB_CU_UP_ID);
|
||||
e1Setup->gNB_cu_up_id = gnb_id;
|
||||
}
|
||||
}
|
||||
return msgConfig;
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#include "common/utils/LOG/log.h"
|
||||
|
||||
#include "openair2/XNAP/xnap_gNB_task.h"
|
||||
#include "x2ap_eNB.h"
|
||||
#include "intertask_interface.h"
|
||||
#include "ngap_gNB.h"
|
||||
@@ -59,6 +60,7 @@ extern unsigned char NB_gNB_INST;
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
#define GNB_REGISTER_RETRY_DELAY 10
|
||||
#define XNAP_GNB_REGISTER_RETRY_DELAY 10
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
|
||||
@@ -116,6 +118,21 @@ uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end) {
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
void gNB_app_register_xn(uint32_t gnb_id_num)
|
||||
{
|
||||
MessageDef *msg;
|
||||
|
||||
for (uint32_t gnb_id = 0; (gnb_id < gnb_id_num); gnb_id++) {
|
||||
msg = itti_alloc_new_message(TASK_GNB_APP, 0, XNAP_REGISTER_GNB_REQ);
|
||||
LOG_I(XNAP, "GNB_ID: %d \n", gnb_id);
|
||||
uint64_t id;
|
||||
char *name = NULL;
|
||||
read_xn_setup(&id, &name, &XNAP_REGISTER_GNB_REQ(msg).setup_req);
|
||||
XNAP_REGISTER_GNB_REQ(msg).net_config = Read_IPconfig_Xn();
|
||||
XNAP_REGISTER_GNB_REQ(msg).gNB_name = name;
|
||||
itti_send_msg_to_task(TASK_XNAP, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg);
|
||||
}
|
||||
}
|
||||
|
||||
void *gNB_app_task(void *args_p)
|
||||
{
|
||||
@@ -128,6 +145,11 @@ void *gNB_app_task(void *args_p)
|
||||
(void)instance;
|
||||
|
||||
int cell_to_activate = 0;
|
||||
|
||||
if (is_xnap_enabled()) {
|
||||
gNB_app_register_xn (RC.nb_nr_inst);
|
||||
}
|
||||
|
||||
itti_mark_task_ready (TASK_GNB_APP);
|
||||
ngran_node_t node_type = get_node_type();
|
||||
|
||||
@@ -146,8 +168,7 @@ void *gNB_app_task(void *args_p)
|
||||
if (node_type == ngran_gNB_CUCP) {
|
||||
if (itti_create_task(TASK_CUCP_E1, E1AP_CUCP_task, NULL) < 0)
|
||||
AssertFatal(false, "Create task for E1AP CP failed\n");
|
||||
E1_t e1type = CPtype;
|
||||
MessageDef *msg = RCconfig_NR_CU_E1(&e1type);
|
||||
MessageDef *msg = RCconfig_NR_CU_E1(true);
|
||||
AssertFatal(msg != NULL, "Send inti to task for E1AP CP failed\n");
|
||||
// this sends the E1AP_REGISTER_REQ to CU-CP so it sets up the socket
|
||||
// it does NOT use the E1AP part
|
||||
|
||||
@@ -35,4 +35,5 @@
|
||||
void *gNB_app_task(void *args_p);
|
||||
uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end);
|
||||
uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end);
|
||||
void gNB_app_register_xn(uint32_t gnb_id_num);
|
||||
#endif /* GNB_APP_H_ */
|
||||
|
||||
@@ -93,6 +93,7 @@
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
|
||||
extern uint16_t sf_ahead;
|
||||
int macrlc_has_f1 = 0;
|
||||
|
||||
// synchronization raster per band tables (Rel.15)
|
||||
// (38.101-1 Table 5.4.3.3-1 and 38.101-2 Table 5.4.3.3-1)
|
||||
@@ -158,8 +159,7 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) {
|
||||
scc->uplinkConfigCommon = CALLOC(1,sizeof(struct NR_UplinkConfigCommon));
|
||||
scc->uplinkConfigCommon->frequencyInfoUL = CALLOC(1,sizeof(struct NR_FrequencyInfoUL));
|
||||
scc->uplinkConfigCommon->initialUplinkBWP = CALLOC(1,sizeof(struct NR_BWP_UplinkCommon));
|
||||
//scc->supplementaryUplinkConfig = CALLOC(1,sizeof(struct NR_UplinkConfigCommon));
|
||||
scc->n_TimingAdvanceOffset = CALLOC(1, sizeof(long));
|
||||
//scc->supplementaryUplinkConfig = CALLOC(1,sizeof(struct NR_UplinkConfigCommon));
|
||||
scc->ssb_PositionsInBurst = CALLOC(1,sizeof(struct NR_ServingCellConfigCommon__ssb_PositionsInBurst));
|
||||
scc->ssb_periodicityServingCell = CALLOC(1,sizeof(long));
|
||||
// scc->rateMatchPatternToAddModList = CALLOC(1,sizeof(struct NR_ServingCellConfigCommon__rateMatchPatternToAddModList));
|
||||
@@ -278,8 +278,7 @@ void fill_scc_sim(NR_ServingCellConfigCommon_t *scc,uint64_t *ssb_bitmap,int N_R
|
||||
scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier=0;
|
||||
scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing=mu_dl;
|
||||
scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth=N_RB_DL;
|
||||
scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth =
|
||||
PRBalloc_to_locationandbandwidth(N_RB_DL, 0);
|
||||
scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth=275*(N_RB_DL-1);
|
||||
scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing=mu_dl;//NR_SubcarrierSpacing_kHz30;
|
||||
*scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero=12;
|
||||
*scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero=0;
|
||||
@@ -299,7 +298,7 @@ void fill_scc_sim(NR_ServingCellConfigCommon_t *scc,uint64_t *ssb_bitmap,int N_R
|
||||
scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing=mu_ul;
|
||||
scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth=N_RB_UL;
|
||||
*scc->uplinkConfigCommon->frequencyInfoUL->p_Max=20;
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth = PRBalloc_to_locationandbandwidth(N_RB_UL, 0);
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth=275*(N_RB_UL-1);
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing=mu_ul;//NR_SubcarrierSpacing_kHz30;
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex=98;
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM=NR_RACH_ConfigGeneric__msg1_FDM_one;
|
||||
@@ -440,11 +439,6 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap) {
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing=NULL;
|
||||
}
|
||||
|
||||
if ((int)*scc->n_TimingAdvanceOffset == -1) {
|
||||
free(scc->n_TimingAdvanceOffset);
|
||||
scc->n_TimingAdvanceOffset = NULL;
|
||||
}
|
||||
|
||||
// check pucch_ResourceConfig
|
||||
AssertFatal(*scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_ResourceCommon < 2,
|
||||
"pucch_ResourceConfig should be 0 or 1 for now\n");
|
||||
@@ -1034,9 +1028,7 @@ static NR_ServingCellConfig_t *get_scd_config(configmodule_interface_t *cfg)
|
||||
}
|
||||
|
||||
static int read_du_cell_info(configmodule_interface_t *cfg,
|
||||
bool separate_du,
|
||||
uint32_t *gnb_id,
|
||||
uint64_t *gnb_du_id,
|
||||
uint64_t *id,
|
||||
char **name,
|
||||
f1ap_served_cell_info_t *info,
|
||||
int max_cell_info)
|
||||
@@ -1053,11 +1045,7 @@ static int read_du_cell_info(configmodule_interface_t *cfg,
|
||||
|
||||
// Output a list of all eNBs.
|
||||
config_getlist(cfg, &GNBParamList, GNBParams, sizeof(GNBParams) / sizeof(paramdef_t), NULL);
|
||||
|
||||
// read the gNB-ID. The DU itself only needs the gNB-DU ID, but some (e.g.,
|
||||
// E2 agent) need the gNB-ID as well if it is running in a separate process
|
||||
AssertFatal(config_isparamset(GNBParamList.paramarray[0], GNB_GNB_ID_IDX), "%s is not defined in configuration file\n", GNB_CONFIG_STRING_GNB_ID);
|
||||
*gnb_id = *GNBParamList.paramarray[0][GNB_GNB_ID_IDX].uptr;
|
||||
AssertFatal(GNBParamList.paramarray[0][GNB_GNB_ID_IDX].uptr != NULL, "gNB id %u is not defined in configuration file\n", 0);
|
||||
|
||||
AssertFatal(strcmp(GNBSParams[GNB_ACTIVE_GNBS_IDX].strlistptr[0], *GNBParamList.paramarray[0][GNB_GNB_NAME_IDX].strptr) == 0,
|
||||
"no active gNB found/mismatch of gNBs: %s vs %s\n",
|
||||
@@ -1074,19 +1062,9 @@ static int read_du_cell_info(configmodule_interface_t *cfg,
|
||||
paramlist_def_t PLMNParamList = {GNB_CONFIG_STRING_PLMN_LIST, NULL, 0};
|
||||
config_getlist(cfg, &PLMNParamList, PLMNParams, sizeof(PLMNParams) / sizeof(paramdef_t), aprefix);
|
||||
|
||||
// if fronthaul is F1, require gNB_DU_ID, else use gNB_ID
|
||||
if (separate_du) {
|
||||
AssertFatal(config_isparamset(GNBParamList.paramarray[0], GNB_GNB_DU_ID_IDX), "%s is not defined in configuration file\n", GNB_CONFIG_STRING_GNB_DU_ID);
|
||||
*gnb_du_id = *GNBParamList.paramarray[0][GNB_GNB_DU_ID_IDX].u64ptr;
|
||||
} else {
|
||||
AssertFatal(!config_isparamset(GNBParamList.paramarray[0], GNB_GNB_DU_ID_IDX),
|
||||
"%s should not be defined in configuration file for monolithic gNB\n",
|
||||
GNB_CONFIG_STRING_GNB_DU_ID);
|
||||
*gnb_du_id = *gnb_id; // the gNB-DU ID is equal to the gNB ID, since the config has no gNB-DU ID
|
||||
}
|
||||
|
||||
*id = *(GNBParamList.paramarray[0][GNB_GNB_ID_IDX].uptr);
|
||||
*name = strdup(*(GNBParamList.paramarray[0][GNB_GNB_NAME_IDX].strptr));
|
||||
info->tac = malloc(sizeof(*info->tac));
|
||||
info->tac = calloc(1,sizeof(*info->tac));
|
||||
AssertFatal(info->tac != NULL, "out of memory\n");
|
||||
*info->tac = *GNBParamList.paramarray[0][GNB_TRACKING_AREA_CODE_IDX].uptr;
|
||||
info->plmn.mcc = *PLMNParamList.paramarray[0][GNB_MOBILE_COUNTRY_CODE_IDX].uptr;
|
||||
@@ -1268,8 +1246,7 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
|
||||
if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_RRC") == 0) {
|
||||
// check number of instances is same as RRC/PDCP
|
||||
|
||||
} else if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "f1") == 0
|
||||
|| strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "cudu") == 0) {
|
||||
} else if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "f1") == 0) {
|
||||
printf("Configuring F1 interfaces for MACRLC\n");
|
||||
RC.nrmac[j]->eth_params_n.local_if_name = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_IF_NAME_IDX].strptr));
|
||||
RC.nrmac[j]->eth_params_n.my_addr = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_ADDRESS_IDX].strptr));
|
||||
@@ -1278,6 +1255,18 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
|
||||
RC.nrmac[j]->eth_params_n.remote_portc = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTC_IDX].iptr);
|
||||
RC.nrmac[j]->eth_params_n.my_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTD_IDX].iptr);
|
||||
RC.nrmac[j]->eth_params_n.remote_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTD_IDX].iptr);
|
||||
;
|
||||
RC.nrmac[j]->eth_params_n.transp_preference = ETH_UDP_MODE;
|
||||
macrlc_has_f1 = 1;
|
||||
} else if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "cudu") == 0) {
|
||||
RC.nrmac[j]->eth_params_n.local_if_name = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_IF_NAME_IDX].strptr));
|
||||
RC.nrmac[j]->eth_params_n.my_addr = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_ADDRESS_IDX].strptr));
|
||||
RC.nrmac[j]->eth_params_n.remote_addr = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_ADDRESS_IDX].strptr));
|
||||
RC.nrmac[j]->eth_params_n.my_portc = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTC_IDX].iptr);
|
||||
RC.nrmac[j]->eth_params_n.remote_portc = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTC_IDX].iptr);
|
||||
RC.nrmac[j]->eth_params_n.my_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTD_IDX].iptr);
|
||||
RC.nrmac[j]->eth_params_n.remote_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTD_IDX].iptr);
|
||||
;
|
||||
RC.nrmac[j]->eth_params_n.transp_preference = ETH_UDP_MODE;
|
||||
} else { // other midhaul
|
||||
AssertFatal(1 == 0, "MACRLC %d: %s unknown northbound midhaul\n", j, *(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr));
|
||||
@@ -1319,11 +1308,10 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
|
||||
memcpy(RC.nrmac[j]->ulprbbl, prbbl, 275 * sizeof(prbbl[0]));
|
||||
} // for (j=0;j<RC.nb_nr_macrlc_inst;j++)
|
||||
|
||||
uint64_t gnb_du_id = 0;
|
||||
uint32_t gnb_id = 0;
|
||||
uint64_t id;
|
||||
char *name = NULL;
|
||||
f1ap_served_cell_info_t info;
|
||||
read_du_cell_info(cfg, NODE_IS_DU(node_type), &gnb_id, &gnb_du_id, &name, &info, 1);
|
||||
read_du_cell_info(cfg, &id, &name, &info, 1);
|
||||
|
||||
if (get_softmodem_params()->sa)
|
||||
nr_mac_configure_sib1(RC.nrmac[0], &info.plmn, info.nr_cellid, *info.tac);
|
||||
@@ -1332,10 +1320,9 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
|
||||
// and store it at MAC for sending later
|
||||
NR_BCCH_BCH_Message_t *mib = RC.nrmac[0]->common_channels[0].mib;
|
||||
const NR_BCCH_DL_SCH_Message_t *sib1 = RC.nrmac[0]->common_channels[0].sib1;
|
||||
f1ap_setup_req_t *req = RC_read_F1Setup(gnb_du_id, name, &info, scc, mib, sib1);
|
||||
f1ap_setup_req_t *req = RC_read_F1Setup(id, name, &info, scc, mib, sib1);
|
||||
AssertFatal(req != NULL, "could not read F1 Setup information\n");
|
||||
RC.nrmac[0]->f1_config.setup_req = req;
|
||||
RC.nrmac[0]->f1_config.gnb_id = gnb_id;
|
||||
|
||||
free(name); /* read_du_cell_info() allocated memory */
|
||||
|
||||
@@ -1557,12 +1544,12 @@ void RCconfig_NRRRC(gNB_RRC_INST *rrc)
|
||||
printf("NRRRC %u: Southbound Transport %s\n",i,*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr));
|
||||
|
||||
rrc->node_type = get_node_type();
|
||||
rrc->node_id = gnb_id;
|
||||
if (NODE_IS_CU(rrc->node_type)) {
|
||||
paramdef_t SCTPParams[] = GNBSCTPPARAMS_DESC;
|
||||
char aprefix[MAX_OPTNAME_SIZE*2 + 8];
|
||||
sprintf(aprefix,"%s.[%u].%s",GNB_CONFIG_STRING_GNB_LIST,i,GNB_CONFIG_STRING_SCTP_CONFIG);
|
||||
config_get(config_get_if(), SCTPParams, sizeofArray(SCTPParams), aprefix);
|
||||
rrc->node_id = gnb_id;
|
||||
LOG_I(GNB_APP,"F1AP: gNB_CU_id[%d] %d\n",k,rrc->node_id);
|
||||
rrc->node_name = strdup(*(GNBParamList.paramarray[0][GNB_GNB_NAME_IDX].strptr));
|
||||
LOG_I(GNB_APP,"F1AP: gNB_CU_name[%d] %s\n",k,rrc->node_name);
|
||||
@@ -2227,6 +2214,147 @@ int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_up
|
||||
return(ret);
|
||||
}
|
||||
|
||||
void read_xn_setup(uint64_t *id, char **name, xnap_setup_req_t *req)
|
||||
{
|
||||
memset(req, 0, sizeof(*req));
|
||||
xnap_served_cell_info_t *info = &req->info;
|
||||
paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
|
||||
paramdef_t GNBParams[] = GNBPARAMS_DESC;
|
||||
paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST, NULL, 0};
|
||||
config_get(config_get_if(), GNBSParams, sizeofArray(GNBSParams), NULL);
|
||||
int num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt;
|
||||
AssertFatal(num_gnbs == 1, "Failed to parse config file\n");
|
||||
// Output a list of all gNBs.
|
||||
config_getlist(config_get_if(), &GNBParamList, GNBParams, sizeof(GNBParams) / sizeof(paramdef_t), NULL);
|
||||
AssertFatal(config_isparamset(GNBParamList.paramarray[0], GNB_GNB_ID_IDX),
|
||||
"%s is not defined in configuration file\n",
|
||||
GNB_CONFIG_STRING_GNB_ID);
|
||||
*id = *GNBParamList.paramarray[0][GNB_GNB_ID_IDX].uptr;
|
||||
AssertFatal(strcmp(GNBSParams[GNB_ACTIVE_GNBS_IDX].strlistptr[0], *GNBParamList.paramarray[0][GNB_GNB_NAME_IDX].strptr) == 0,
|
||||
"no active gNB found/mismatch of gNBs: %s vs %s\n",
|
||||
GNBSParams[GNB_ACTIVE_GNBS_IDX].strlistptr[0],
|
||||
*GNBParamList.paramarray[0][GNB_GNB_NAME_IDX].strptr);
|
||||
|
||||
char aprefix[MAX_OPTNAME_SIZE * 2 + 8];
|
||||
sprintf(aprefix, "%s.[0]", GNB_CONFIG_STRING_GNB_LIST);
|
||||
paramdef_t PLMNParams[] = GNBPLMNPARAMS_DESC;
|
||||
/* map parameter checking array instances to parameter definition array instances */
|
||||
checkedparam_t config_check_PLMNParams[] = PLMNPARAMS_CHECK;
|
||||
for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I)
|
||||
PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]);
|
||||
paramlist_def_t PLMNParamList = {GNB_CONFIG_STRING_PLMN_LIST, NULL, 0};
|
||||
config_getlist(config_get_if(), &PLMNParamList, PLMNParams, sizeofArray(PLMNParams), aprefix);
|
||||
*name = strdup(*(GNBParamList.paramarray[0][GNB_GNB_NAME_IDX].strptr));
|
||||
info->tac = *GNBParamList.paramarray[0][GNB_TRACKING_AREA_CODE_IDX].uptr;
|
||||
info->plmn.mcc = *PLMNParamList.paramarray[0][GNB_MOBILE_COUNTRY_CODE_IDX].uptr;
|
||||
info->plmn.mnc = *PLMNParamList.paramarray[0][GNB_MOBILE_NETWORK_CODE_IDX].uptr;
|
||||
info->plmn.mnc_digit_length = *PLMNParamList.paramarray[0][GNB_MNC_DIGIT_LENGTH].u8ptr;
|
||||
AssertFatal((info->plmn.mnc_digit_length == 2) || (info->plmn.mnc_digit_length == 3),
|
||||
"BAD MNC DIGIT LENGTH %d",
|
||||
info->plmn.mnc_digit_length);
|
||||
info->nr_cellid = (uint64_t) * (GNBParamList.paramarray[0][GNB_NRCELLID_IDX].u64ptr);
|
||||
paramdef_t SNSSAIParams[] = GNBSNSSAIPARAMS_DESC;
|
||||
checkedparam_t config_check_SNSSAIParams[] = SNSSAIPARAMS_CHECK;
|
||||
for (int J = 0; J < sizeofArray(SNSSAIParams); ++J)
|
||||
SNSSAIParams[J].chkPptr = &(config_check_SNSSAIParams[J]);
|
||||
paramlist_def_t SNSSAIParamList = {GNB_CONFIG_STRING_SNSSAI_LIST, NULL, 0};
|
||||
config_getlist(config_get_if(), &SNSSAIParamList, SNSSAIParams, sizeofArray(SNSSAIParams), aprefix);
|
||||
req->num_snssai = SNSSAIParamList.numelt;
|
||||
for (int s = 0; s < SNSSAIParamList.numelt; ++s) {
|
||||
req->snssai[s].sst = *SNSSAIParamList.paramarray[s][GNB_SLICE_SERVICE_TYPE_IDX].uptr;
|
||||
req->snssai[s].sd = (*SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr & 0xffffff);
|
||||
}
|
||||
NR_ServingCellConfigCommon_t *scc = get_scc_config(config_get_if(), 6);
|
||||
info->nr_pci = *scc->physCellId;
|
||||
struct NR_FrequencyInfoDL *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
|
||||
if (scc->tdd_UL_DL_ConfigurationCommon) {
|
||||
info->mode = XNAP_MODE_TDD;
|
||||
xnap_tdd_info_t *tdd = &info->tdd;
|
||||
tdd->freqinfo.arfcn = frequencyInfoDL->absoluteFrequencyPointA;
|
||||
tdd->tbw.scs = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
tdd->tbw.nrb = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
|
||||
tdd->freqinfo.band = *frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
} else {
|
||||
info->mode = XNAP_MODE_FDD;
|
||||
xnap_fdd_info_t *fdd = &info->fdd;
|
||||
fdd->dl_freqinfo.arfcn = frequencyInfoDL->absoluteFrequencyPointA;
|
||||
fdd->ul_freqinfo.arfcn = *scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA;
|
||||
fdd->dl_tbw.scs = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
fdd->ul_tbw.scs = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
fdd->dl_tbw.nrb = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
|
||||
fdd->ul_tbw.nrb = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
|
||||
fdd->dl_freqinfo.band = *frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
fdd->ul_freqinfo.band = *scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0];
|
||||
}
|
||||
info->measurement_timing_information = "0";
|
||||
req->gNB_id = *id;
|
||||
req->tai_support = info->tac;
|
||||
req->plmn_support = info->plmn;
|
||||
}
|
||||
|
||||
xnap_net_config_t Read_IPconfig_Xn(void)
|
||||
{
|
||||
char *cidr = NULL;
|
||||
char *address = NULL;
|
||||
char *gnb_ipv4_address_for_NGU = NULL;
|
||||
uint32_t gnb_port_for_NGU = 0;
|
||||
char *gnb_ipv4_address_for_S1U = NULL;
|
||||
uint32_t gnb_port_for_S1U = 0;
|
||||
xnap_net_config_t nc = {0};
|
||||
paramdef_t XnParams[] = XnPARAMS_DESC;
|
||||
paramlist_def_t XnParamList = {GNB_CONFIG_STRING_TARGET_GNB_Xn_IP_ADDRESS, NULL, 0};
|
||||
paramdef_t NETParams[] = GNBNETPARAMS_DESC;
|
||||
paramdef_t SCTPParams[] = GNBSCTPPARAMS_DESC;
|
||||
char aprefix[MAX_OPTNAME_SIZE * 2 + 8];
|
||||
config_getlist(config_get_if(), &XnParamList, XnParams, sizeofArray(XnParams), aprefix);
|
||||
AssertFatal(XnParamList.numelt <= XNAP_MAX_NB_GNB_IP_ADDRESS,
|
||||
"value of XnParamList.numelt %d must be lower than XnAP_MAX_NB_GNB_IP_ADDRESS %d value: reconsider to increase "
|
||||
"XNAP_MAX_NB_GNB_IP_ADDRESS\n",
|
||||
XnParamList.numelt,
|
||||
XNAP_MAX_NB_GNB_IP_ADDRESS);
|
||||
for (int l = 0; l < XnParamList.numelt; l++) {
|
||||
nc.nb_xn += 1;
|
||||
strcpy(nc.target_gnb_xn_ip_address[l].ipv4_address, *(XnParamList.paramarray[l][GNB_Xn_IPV4_ADDRESS_IDX].strptr));
|
||||
strcpy(nc.target_gnb_xn_ip_address[l].ipv6_address, *(XnParamList.paramarray[l][GNB_Xn_IPV6_ADDRESS_IDX].strptr));
|
||||
|
||||
if (strcmp(*(XnParamList.paramarray[l][GNB_Xn_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) {
|
||||
nc.target_gnb_xn_ip_address[l].ipv4 = 1;
|
||||
nc.target_gnb_xn_ip_address[l].ipv6 = 0;
|
||||
} else if (strcmp(*(XnParamList.paramarray[l][GNB_Xn_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) {
|
||||
nc.target_gnb_xn_ip_address[l].ipv4 = 0;
|
||||
nc.target_gnb_xn_ip_address[l].ipv6 = 1;
|
||||
} else if (strcmp(*(XnParamList.paramarray[l][GNB_Xn_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) {
|
||||
nc.target_gnb_xn_ip_address[l].ipv4 = 1;
|
||||
nc.target_gnb_xn_ip_address[l].ipv6 = 1;
|
||||
}
|
||||
}
|
||||
sprintf(aprefix, "%s.[%i].%s", GNB_CONFIG_STRING_GNB_LIST, 0, GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
|
||||
// NETWORK_INTERFACES
|
||||
config_get(config_get_if(), NETParams, sizeofArray(NETParams), aprefix);
|
||||
nc.gnb_port_for_XNC = (uint32_t) * (NETParams[GNB_PORT_FOR_XNC_IDX].uptr);
|
||||
if ((NETParams[GNB_IPV4_ADDR_FOR_XNC_IDX].strptr == NULL) || (nc.gnb_port_for_XNC == 0)) {
|
||||
LOG_E(RRC, "Add gNB IPv4 address and/or port for XNC in the CONF file!\n");
|
||||
exit(1);
|
||||
}
|
||||
cidr = *(NETParams[GNB_IPV4_ADDR_FOR_XNC_IDX].strptr);
|
||||
char *save = NULL;
|
||||
address = strtok_r(cidr, "/", &save);
|
||||
nc.gnb_xn_ip_address.ipv6 = 0;
|
||||
nc.gnb_xn_ip_address.ipv4 = 1;
|
||||
strcpy(nc.gnb_xn_ip_address.ipv4_address, address);
|
||||
|
||||
// SCTP SETTING
|
||||
nc.sctp_streams.sctp_out_streams = SCTP_OUT_STREAMS;
|
||||
nc.sctp_streams.sctp_in_streams = SCTP_IN_STREAMS;
|
||||
if (get_softmodem_params()->sa) {
|
||||
// sprintf(aprefix, "%s.[%i].%s", GNB_CONFIG_STRING_GNB_LIST, 0, GNB_CONFIG_STRING_SCTP_CONFIG);
|
||||
config_get(config_get_if(), SCTPParams, sizeofArray(SCTPParams), aprefix);
|
||||
nc.sctp_streams.sctp_in_streams = (uint16_t) * (SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr);
|
||||
nc.sctp_streams.sctp_out_streams = (uint16_t) * (SCTPParams[GNB_SCTP_OUTSTREAMS_IDX].uptr);
|
||||
}
|
||||
return nc;
|
||||
}
|
||||
|
||||
ngran_node_t get_node_type(void)
|
||||
{
|
||||
paramdef_t MacRLC_Params[] = MACRLCPARAMS_DESC;
|
||||
@@ -2249,7 +2377,7 @@ ngran_node_t get_node_type(void)
|
||||
RC.nb_nr_macrlc_inst = MacRLC_ParamList.numelt;
|
||||
for (int j = 0; j < RC.nb_nr_macrlc_inst; j++) {
|
||||
if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "f1") == 0) {
|
||||
return ngran_gNB_DU; // MACRLCs present in config: it must be a DU
|
||||
macrlc_has_f1 = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2263,9 +2391,10 @@ ngran_node_t get_node_type(void)
|
||||
return ngran_gNB_CUUP;
|
||||
else
|
||||
return ngran_gNB_CU;
|
||||
} else {
|
||||
} else if (macrlc_has_f1 == 0)
|
||||
return ngran_gNB;
|
||||
}
|
||||
else
|
||||
return ngran_gNB_DU;
|
||||
}
|
||||
|
||||
#ifdef E2_AGENT
|
||||
@@ -2278,14 +2407,7 @@ e2_agent_args_t RCconfig_NR_E2agent(void)
|
||||
LOG_W(GNB_APP, "configuration file does not contain a \"%s\" section, applying default parameters from FlexRIC\n", CONFIG_STRING_E2AGENT);
|
||||
return (e2_agent_args_t) { 0 };
|
||||
}
|
||||
|
||||
bool enabled = config_isparamset(e2agent_params, E2AGENT_CONFIG_SMDIR_IDX)
|
||||
&& config_isparamset(e2agent_params, E2AGENT_CONFIG_IP_IDX);
|
||||
e2_agent_args_t dst = {.enabled = enabled};
|
||||
if (!enabled) {
|
||||
LOG_W(GNB_APP, "E2 agent is DISABLED (for activation, define .%s.{%s,%s} parameters)\n", CONFIG_STRING_E2AGENT, E2AGENT_CONFIG_IP, E2AGENT_CONFIG_SMDIR);
|
||||
return dst;
|
||||
}
|
||||
e2_agent_args_t dst = {0};
|
||||
|
||||
if (e2agent_params[E2AGENT_CONFIG_SMDIR_IDX].strptr != NULL)
|
||||
dst.sm_dir = *e2agent_params[E2AGENT_CONFIG_SMDIR_IDX].strptr;
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "rrc_messages_types.h"
|
||||
#include "intertask_interface.h"
|
||||
#include "RRC/NR/nr_rrc_defs.h"
|
||||
#include "openair2/COMMON/xnap_messages_types.h"
|
||||
|
||||
#define IPV4_STR_ADDR_TO_INT_NWBO(AdDr_StR,NwBo,MeSsAgE ) do {\
|
||||
struct in_addr inp;\
|
||||
@@ -108,6 +109,8 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i);
|
||||
void wait_f1_setup_response(void);
|
||||
int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_update_t *gnb_cu_cfg_update);
|
||||
MessageDef *RCconfig_NR_CU_E1(const E1_t *entity);
|
||||
void read_xn_setup(uint64_t *id, char **name, xnap_setup_req_t *req);
|
||||
xnap_net_config_t Read_IPconfig_Xn(void);
|
||||
ngran_node_t get_node_type(void);
|
||||
|
||||
#ifdef E2_AGENT
|
||||
|
||||
@@ -131,6 +131,7 @@ typedef enum {
|
||||
#define GNB_CONFIG_STRING_GNB_DU_ID "gNB_DU_ID"
|
||||
#define GNB_CONFIG_STRING_GNB_CU_UP_ID "gNB_CU_UP_ID"
|
||||
|
||||
#define GNB_CONFIG_STRING_XN "enable_xn"
|
||||
#define GNB_CONFIG_HLP_STRING_ENABLE_SDAP "enable the SDAP layer\n"
|
||||
#define GNB_CONFIG_HLP_FORCE256QAMOFF "suppress activation of 256 QAM despite UE support"
|
||||
#define GNB_CONFIG_HLP_STRING_DRBS "Number of total DRBs to establish, including the mandatory for PDU SEssion (default=1)\n"
|
||||
@@ -141,7 +142,6 @@ typedef enum {
|
||||
/* cell configuration parameters */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
// clang-format off
|
||||
#define GNBPARAMS_DESC {\
|
||||
{GNB_CONFIG_STRING_GNB_ID, NULL, 0, .uptr=NULL, .defintval=0, TYPE_UINT, 0}, \
|
||||
{GNB_CONFIG_STRING_CELL_TYPE, NULL, 0, .strptr=NULL, .defstrval="CELL_MACRO_GNB", TYPE_STRING, 0}, \
|
||||
@@ -171,11 +171,7 @@ typedef enum {
|
||||
{GNB_CONFIG_STRING_FORCE256QAMOFF, GNB_CONFIG_HLP_FORCE256QAMOFF, PARAMFLAG_BOOL, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \
|
||||
{GNB_CONFIG_STRING_ENABLE_SDAP, GNB_CONFIG_HLP_STRING_ENABLE_SDAP, PARAMFLAG_BOOL,.iptr=NULL, .defintval=0, TYPE_INT, 0}, \
|
||||
{GNB_CONFIG_STRING_DRBS, GNB_CONFIG_HLP_STRING_DRBS, 0, .iptr=NULL, .defintval=1, TYPE_INT, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_DU_ID, GNB_CONFIG_HLP_GNB_DU_ID, 0, .u64ptr=NULL, .defint64val=1, TYPE_UINT64, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_CU_UP_ID, GNB_CONFIG_HLP_GNB_CU_UP_ID, 0, .u64ptr=NULL, .defint64val=1, TYPE_UINT64, 0}, \
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
|
||||
#define GNB_GNB_ID_IDX 0
|
||||
#define GNB_CELL_TYPE_IDX 1
|
||||
@@ -205,8 +201,6 @@ typedef enum {
|
||||
#define GNB_FORCE256QAMOFF_IDX 25
|
||||
#define GNB_ENABLE_SDAP_IDX 26
|
||||
#define GNB_DRBS 27
|
||||
#define GNB_GNB_DU_ID_IDX 28
|
||||
#define GNB_GNB_CU_UP_ID_IDX 29
|
||||
|
||||
#define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
|
||||
#define GNBPARAMS_CHECK { \
|
||||
@@ -345,6 +339,8 @@ typedef enum {
|
||||
#define GNB_PORT_FOR_NGU_IDX 4
|
||||
#define GNB_IPV4_ADDR_FOR_X2C_IDX 5
|
||||
#define GNB_PORT_FOR_X2C_IDX 6
|
||||
#define GNB_IPV4_ADDR_FOR_XNC_IDX 7
|
||||
#define GNB_PORT_FOR_XNC_IDX 8
|
||||
|
||||
/* S1 interface configuration parameters names */
|
||||
#define GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_S1_MME "GNB_INTERFACE_NAME_FOR_S1_MME"
|
||||
@@ -363,6 +359,10 @@ typedef enum {
|
||||
#define GNB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_X2C "GNB_IPV4_ADDRESS_FOR_X2C"
|
||||
#define GNB_CONFIG_STRING_ENB_PORT_FOR_X2C "GNB_PORT_FOR_X2C"
|
||||
|
||||
/* Xn interface configuration parameters names */
|
||||
#define GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_XNC "GNB_IPV4_ADDRESS_FOR_XNC"
|
||||
#define GNB_CONFIG_STRING_GNB_PORT_FOR_XNC "GNB_PORT_FOR_XNC"
|
||||
|
||||
/*--------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* S1 interface configuration parameters */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
@@ -375,6 +375,8 @@ typedef enum {
|
||||
{GNB_CONFIG_STRING_GNB_PORT_FOR_NGU, NULL, 0, .uptr=&gnb_port_for_NGU, .defintval=2152L, TYPE_UINT, 0}, \
|
||||
{GNB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_X2C, NULL, 0, .strptr=NULL, .defstrval=NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_ENB_PORT_FOR_X2C, NULL, 0, .uptr=NULL, .defintval=0L, TYPE_UINT, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_XNC, NULL, 0, .strptr=NULL, .defstrval=NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_PORT_FOR_XNC, NULL, 0, .uptr=NULL, .defintval=0L, TYPE_UINT, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_S1U, NULL, 0, .strptr=NULL, .defstrval=NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_S1U, NULL, 0, .strptr=&gnb_ipv4_address_for_S1U, .defstrval="127.0.0.1",TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_PORT_FOR_S1U, NULL, 0, .uptr=&gnb_port_for_S1U, .defintval=2152L, TYPE_UINT, 0} \
|
||||
@@ -382,6 +384,29 @@ typedef enum {
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* Xn configuration parameters section name */
|
||||
#define GNB_CONFIG_STRING_TARGET_GNB_Xn_IP_ADDRESS "target_gnb_xn_ip_address"
|
||||
|
||||
/* Xn configuration parameters names */
|
||||
#define GNB_CONFIG_STRING_TARGET_GNB_Xn_IPV4_ADDRESS "ipv4"
|
||||
#define GNB_CONFIG_STRING_TARGET_GNB_Xn_IPV6_ADDRESS "ipv6"
|
||||
#define GNB_CONFIG_STRING_TARGET_GNB_Xn_IP_ADDRESS_PREFERENCE "preference"
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* Xn configuration parameters */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define XnPARAMS_DESC { \
|
||||
{GNB_CONFIG_STRING_TARGET_GNB_Xn_IPV4_ADDRESS, NULL, 0, .uptr=NULL, .defstrval=NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_TARGET_GNB_Xn_IPV6_ADDRESS, NULL, 0, .uptr=NULL, .defstrval=NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_TARGET_GNB_Xn_IP_ADDRESS_PREFERENCE, NULL, 0, .uptr=NULL, .defstrval=NULL, TYPE_STRING, 0}, \
|
||||
}
|
||||
|
||||
#define GNB_Xn_IPV4_ADDRESS_IDX 0
|
||||
#define GNB_Xn_IPV6_ADDRESS_IDX 1
|
||||
#define GNB_Xn_IP_ADDRESS_PREFERENCE_IDX 2
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* E1 configuration section */
|
||||
#define GNB_CONFIG_STRING_E1_PARAMETERS "E1_INTERFACE"
|
||||
|
||||
|
||||
@@ -143,6 +143,9 @@
|
||||
#include "common/ran_context.h"
|
||||
#include "conversions.h"
|
||||
|
||||
#include "cmake_targets/ran_build/build/openair2/RRC/NR/MESSAGES/NR_HandoverPreparationInformation.h"
|
||||
#include "cmake_targets/ran_build/build/openair2/RRC/NR/MESSAGES/NR_HandoverPreparationInformation-IEs.h"
|
||||
#include "cmake_targets/ran_build/build/openair2/RRC/NR/MESSAGES/NR_UE-CapabilityRAT-Container.h"
|
||||
//#define XER_PRINT
|
||||
|
||||
typedef struct xer_sprint_string_s {
|
||||
@@ -1135,7 +1138,30 @@ NR_MeasConfig_t *get_defaultMeasConfig(uint32_t ssb_arfcn, int band, int scs)
|
||||
asn1cCallocOne(monr1->ext1->freqBandIndicatorNR, band);
|
||||
mo1->measObject.choice.measObjectNR = monr1;
|
||||
asn1cSeqAdd(&mc->measObjectToAddModList->list, mo1);
|
||||
|
||||
|
||||
NR_MeasObjectToAddMod_t *mo3 = calloc(1, sizeof(*mo3));
|
||||
int module_id;
|
||||
mo3->measObjectId = 3;
|
||||
mo3->measObject.present = NR_MeasObjectToAddMod__measObject_PR_measObjectNR;
|
||||
NR_MeasObjectNR_t *monr3 = calloc(1, sizeof(*monr3));
|
||||
asn1cCallocOne(monr3->ssbFrequency, ssb_arfcn);
|
||||
asn1cCallocOne(monr3->ssbSubcarrierSpacing, scs);
|
||||
for (int i = 0; i < RC.nb_nr_inst; i++) {
|
||||
if ((i != module_id) && RC.nrrrc[i] && RC.nrrrc[i]->configuration.serving_cell_config_common && RC.nrrrc[i]->configuration.serving_cell_config_common->physCellId) {
|
||||
if (monr3->cellsToAddModList == NULL) {
|
||||
monr3->cellsToAddModList = calloc(1, sizeof(*monr3->cellsToAddModList));
|
||||
}
|
||||
NR_CellsToAddMod_t *cell = calloc(1, sizeof(*cell));
|
||||
cell->physCellId = *RC.nrrrc[i]->configuration.serving_cell_config_common->physCellId;
|
||||
ASN_SEQUENCE_ADD(&monr3->cellsToAddModList->list, cell);
|
||||
}
|
||||
}
|
||||
monr3->quantityConfigIndex = 2;
|
||||
monr3->ext1 = calloc(1, sizeof(*monr3->ext1));
|
||||
asn1cCallocOne(monr3->ext1->freqBandIndicatorNR, band);
|
||||
mo3->measObject.choice.measObjectNR = monr3;
|
||||
asn1cSeqAdd(&mc->measObjectToAddModList->list, mo3);
|
||||
//IMRAN
|
||||
// Reporting Configuration: Specifies how reporting should be done. This could be periodic or event-triggered.
|
||||
NR_ReportConfigToAddMod_t *rc = calloc(1, sizeof(*rc));
|
||||
rc->reportConfigId = 1;
|
||||
@@ -1175,6 +1201,82 @@ NR_MeasConfig_t *get_defaultMeasConfig(uint32_t ssb_arfcn, int band, int scs)
|
||||
measid->reportConfigId = 1;
|
||||
asn1cSeqAdd(&mc->measIdToAddModList->list, measid);
|
||||
|
||||
/*Imran*/ /*Requires Verification*/
|
||||
|
||||
/*Event A3*/
|
||||
NR_ReportConfigToAddMod_t *rc_event_A3 = calloc(1, sizeof(*rc_event_A3));
|
||||
rc_event_A3->reportConfigId = 3;
|
||||
rc_event_A3->reportConfig.present = NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR;
|
||||
NR_EventTriggerConfig_t *etrc_event_A3 = calloc(1, sizeof(*etrc_event_A3));
|
||||
etrc_event_A3->eventId.present = NR_EventTriggerConfig__eventId_PR_eventA3;
|
||||
etrc_event_A3->eventId.choice.eventA3 = calloc(1, sizeof(*etrc_event_A3->eventId.choice.eventA3));
|
||||
etrc_event_A3->eventId.choice.eventA3->a3_Offset.present = NR_MeasTriggerQuantityOffset_PR_rsrp;
|
||||
etrc_event_A3->eventId.choice.eventA3->a3_Offset.choice.rsrp = 0; //
|
||||
etrc_event_A3->eventId.choice.eventA3->reportOnLeave = true;
|
||||
etrc_event_A3->eventId.choice.eventA3->hysteresis = 0;
|
||||
etrc_event_A3->eventId.choice.eventA3->timeToTrigger = NR_TimeToTrigger_ms2560;
|
||||
etrc_event_A3->rsType = NR_NR_RS_Type_ssb;
|
||||
etrc_event_A3->reportInterval = NR_ReportInterval_ms1024;
|
||||
etrc_event_A3->reportAmount = NR_EventTriggerConfig__reportAmount_infinity;
|
||||
etrc_event_A3->reportQuantityCell.rsrp = true;
|
||||
etrc_event_A3->reportQuantityCell.rsrq = false;
|
||||
etrc_event_A3->reportQuantityCell.sinr = false;
|
||||
asn1cCallocOne(etrc_event_A3->maxNrofRS_IndexesToReport, 4);
|
||||
etrc_event_A3->maxReportCells = 4;
|
||||
etrc_event_A3->includeBeamMeasurements = false;
|
||||
NR_ReportConfigNR_t *rcnr_event_A3 = calloc(1, sizeof(*rcnr_event_A3));
|
||||
rcnr_event_A3->reportType.present = NR_ReportConfigNR__reportType_PR_eventTriggered;
|
||||
rcnr_event_A3->reportType.choice.eventTriggered = etrc_event_A3;
|
||||
rc_event_A3->reportConfig.choice.reportConfigNR = rcnr_event_A3;
|
||||
asn1cSeqAdd(&mc->reportConfigToAddModList->list, rc_event_A3);
|
||||
|
||||
/*Event A5*/
|
||||
// NR_ReportConfigToAddMod_t *rc_event_A5 = calloc(1, sizeof(*rc_event_A5));
|
||||
// rc_event_A5->reportConfigId = 5;
|
||||
// rc_event_A5->reportConfig.present = NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR;
|
||||
// NR_EventTriggerConfig_t *etrc_event_A5 = calloc(1, sizeof(*etrc_event_A5));
|
||||
// etrc_event_A5->eventId.present = NR_EventTriggerConfig__eventId_PR_eventA5;
|
||||
// etrc_event_A5->eventId.choice.eventA5 = calloc(1, sizeof(*etrc_event_A5->eventId.choice.eventA5));
|
||||
// etrc_event_A5->eventId.choice.eventA5->a5_Threshold1.present = NR_MeasTriggerQuantityOffset_PR_rsrp;
|
||||
// etrc_event_A5->eventId.choice.eventA5->a5_Threshold1.choice.rsrp = 10; // 10 means 5 dB
|
||||
//etrc_event_A5->eventId.choice.eventA5->a5_Threshold2.present = NR_MeasTriggerQuantityOffset_PR_rsrp;
|
||||
// etrc_event_A5->eventId.choice.eventA5->a5_Threshold2.choice.rsrp = 10; // 10 means 5 dB
|
||||
// etrc_event_A5->eventId.choice.eventA5->reportOnLeave = true;
|
||||
// etrc_event_A5->eventId.choice.eventA5->hysteresis = 0;
|
||||
// etrc_event_A5->eventId.choice.eventA5->timeToTrigger = NR_TimeToTrigger_ms2560;
|
||||
// etrc_event_A5->rsType = NR_NR_RS_Type_ssb;
|
||||
// etrc_event_A5->reportInterval = NR_ReportInterval_ms1024;
|
||||
// etrc_event_A5->reportAmount = NR_EventTriggerConfig__reportAmount_infinity;
|
||||
// etrc_event_A53->reportQuantityCell.rsrp = true;
|
||||
// etrc_event_A5->reportQuantityCell.rsrq = false;
|
||||
// etrc_event_A5->reportQuantityCell.sinr = false;
|
||||
// asn1cCallocOne(etrc_event_A5->maxNrofRS_IndexesToReport, 4);
|
||||
// etrc_event_A5->maxReportCells = 4;
|
||||
// etrc_event_A5->includeBeamMeasurements = false;
|
||||
// NR_ReportConfigNR_t *rcnr_event_A5 = calloc(1, sizeof(*rcnr_event_A5));
|
||||
// rcnr_event_A5->reportType.present = NR_ReportConfigNR__reportType_PR_eventTriggered;
|
||||
// rcnr_event_A5->reportType.choice.eventTriggered = etrc_event_A5;
|
||||
// rc_evet_A5->reportConfig.choice.reportConfigNR = rcnr_event_A5;
|
||||
// asn1cSeqAdd(&mc->reportConfigToAddModList->list, rc_event_A5);
|
||||
/*Imran*/
|
||||
// Measurement ID: Identifies how to report measurements of a specific object. This is a many-to-many mapping: a
|
||||
// measurement object could have multiple reporting configurations, a reporting configuration could apply to multiple
|
||||
// objects. A unique ID is used for each object-to-report-config association. When UE sends a MeasurementReport
|
||||
// message, a single ID and related measurements are included in the message.
|
||||
mc->measIdToAddModList = calloc(1, sizeof(*mc->measIdToAddModList));
|
||||
// NR_MeasIdToAddMod_t *measid = calloc(1, sizeof(*measid));
|
||||
|
||||
measid->measId = 1;
|
||||
measid->measObjectId = 1;
|
||||
measid->reportConfigId = 1;
|
||||
asn1cSeqAdd(&mc->measIdToAddModList->list, measid);
|
||||
|
||||
NR_MeasIdToAddMod_t *measid_event_A3 = calloc(1, sizeof(*measid_event_A3));
|
||||
measid_event_A3->measId = 3;
|
||||
measid_event_A3->measObjectId = 3;
|
||||
measid_event_A3->reportConfigId = 3;
|
||||
asn1cSeqAdd(&mc->measIdToAddModList->list, measid_event_A3);
|
||||
|
||||
// Quantity Configuration: Specifies parameters for layer 3 filtering of measurements. Only after filtering, reporting
|
||||
// criteria are evaluated. The formula used is F_n = (1-a)F_(n-1) + a*M_n, where M is the latest measurement, F is the
|
||||
// filtered measurement, and ais based on configured filter coefficient.
|
||||
@@ -1185,6 +1287,28 @@ NR_MeasConfig_t *get_defaultMeasConfig(uint32_t ssb_arfcn, int band, int scs)
|
||||
asn1cCallocOne(qcnr3->quantityConfigCell.csi_RS_FilterConfig.filterCoefficientRSRP, NR_FilterCoefficient_fc6);
|
||||
asn1cSeqAdd(&mc->quantityConfig->quantityConfigNR_List->list, qcnr3);
|
||||
|
||||
/*Imran*/
|
||||
NR_QuantityConfigNR_t *qcnr_event_a3 = calloc(1, sizeof(*qcnr_event_a3));
|
||||
asn1cCallocOne(qcnr_event_a3->quantityConfigCell.ssb_FilterConfig.filterCoefficientRSRP, NR_FilterCoefficient_fc6);
|
||||
asn1cCallocOne(qcnr_event_a3->quantityConfigCell.csi_RS_FilterConfig.filterCoefficientRSRP, NR_FilterCoefficient_fc6);
|
||||
asn1cSeqAdd(&mc->quantityConfig->quantityConfigNR_List->list, qcnr_event_a3);
|
||||
|
||||
NR_QuantityConfigNR_t *qcnr_event_a5 = calloc(1, sizeof(*qcnr_event_a5));
|
||||
asn1cCallocOne(qcnr_event_a5->quantityConfigCell.ssb_FilterConfig.filterCoefficientRSRP, NR_FilterCoefficient_fc6);
|
||||
asn1cCallocOne(qcnr_event_a5->quantityConfigCell.csi_RS_FilterConfig.filterCoefficientRSRP, NR_FilterCoefficient_fc6);
|
||||
asn1cSeqAdd(&mc->quantityConfig->quantityConfigNR_List->list, qcnr_event_a5);
|
||||
/*Imran*/
|
||||
|
||||
// Quantity Configuration: Specifies parameters for layer 3 filtering of measurements. Only after filtering, reporting
|
||||
// criteria are evaluated. The formula used is F_n = (1-a)F_(n-1) + a*M_n, where M is the latest measurement, F is the
|
||||
// filtered measurement, and ais based on configured filter coefficient.
|
||||
/* mc->quantityConfig = calloc(1, sizeof(*mc->quantityConfig));
|
||||
mc->quantityConfig->quantityConfigNR_List = calloc(1, sizeof(*mc->quantityConfig->quantityConfigNR_List));
|
||||
NR_QuantityConfigNR_t *qcnr3 = calloc(1, sizeof(*qcnr3));
|
||||
asn1cCallocOne(qcnr3->quantityConfigCell.ssb_FilterConfig.filterCoefficientRSRP, NR_FilterCoefficient_fc6);
|
||||
asn1cCallocOne(qcnr3->quantityConfigCell.csi_RS_FilterConfig.filterCoefficientRSRP, NR_FilterCoefficient_fc6);
|
||||
asn1cSeqAdd(&mc->quantityConfig->quantityConfigNR_List->list, qcnr3); */
|
||||
|
||||
return mc;
|
||||
}
|
||||
|
||||
@@ -1231,3 +1355,43 @@ uint8_t do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi) {
|
||||
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
|
||||
int do_NRHandoverPreparation(char *ho_buf, int ho_size, NR_UE_NR_Capability_t *ue_nr_cap, int rrc_size) {
|
||||
asn_enc_rval_t enc_rval;
|
||||
NR_HandoverPreparationInformation_t ho;
|
||||
NR_HandoverPreparationInformation_IEs_t *ho_info;
|
||||
NR_UE_CapabilityRAT_Container_t *ue_cap_rat_container;
|
||||
char rrc_buf[rrc_size];
|
||||
memset(rrc_buf, 0, rrc_size);
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UE_NR_Capability,
|
||||
NULL,
|
||||
ue_nr_cap,
|
||||
rrc_buf,
|
||||
rrc_size);
|
||||
/* TODO: free the OCTET_STRING */
|
||||
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
memset(&ho, 0, sizeof(ho));
|
||||
ho.criticalExtensions.present = NR_HandoverPreparationInformation__criticalExtensions_PR_c1;
|
||||
ho.criticalExtensions.choice.c1->present = NR_HandoverPreparationInformation__criticalExtensions__c1_PR_handoverPreparationInformation;
|
||||
ho_info = &ho.criticalExtensions.choice.c1->choice.handoverPreparationInformation;
|
||||
{
|
||||
ue_cap_rat_container = (NR_UE_CapabilityRAT_Container_t *)calloc(1,sizeof(NR_UE_CapabilityRAT_Container_t));
|
||||
ue_cap_rat_container->rat_Type = NR_RAT_Type_nr;
|
||||
AssertFatal (OCTET_STRING_fromBuf(
|
||||
&ue_cap_rat_container->ue_CapabilityRAT_Container,
|
||||
rrc_buf, rrc_size) != -1, "fatal: OCTET_STRING_fromBuf failed\n");
|
||||
asn1cSeqAdd(&ho_info->ue_CapabilityRAT_List.list, ue_cap_rat_container);
|
||||
}
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_HandoverPreparationInformation,
|
||||
NULL,
|
||||
&ho,
|
||||
ho_buf,
|
||||
ho_size);
|
||||
/* TODO: free the OCTET_STRING */
|
||||
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
|
||||
@@ -149,4 +149,6 @@ NR_MeasConfig_t *get_defaultMeasConfig(uint32_t absFreqSSB, int band, int scs);
|
||||
void free_defaultMeasConfig(NR_MeasConfig_t *mc);
|
||||
uint8_t do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi);
|
||||
|
||||
int do_NRHandoverPreparation(char *ho_buf, int ho_size, NR_UE_NR_Capability_t *ue_nr_cap, int rrc_size);
|
||||
|
||||
#endif /* __RRC_NR_MESSAGES_ASN1_MSG__H__ */
|
||||
|
||||
@@ -96,6 +96,8 @@
|
||||
#define NR_UE_MODULE_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!!
|
||||
#define NR_UE_INDEX_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!! used to be -1
|
||||
|
||||
#define MAX_NUM_NR_NEIGH_CELLs 6 /* maximum neighbouring cells number */
|
||||
|
||||
typedef enum {
|
||||
NR_RRC_OK=0,
|
||||
NR_RRC_ConnSetup_failed,
|
||||
@@ -157,6 +159,8 @@ typedef struct HANDOVER_INFO_NR_s {
|
||||
|
||||
uint8_t buf[RRC_BUF_SIZE]; /* ASN.1 encoded handoverCommandMessage */
|
||||
int size; /* size of above message in bytes */
|
||||
sctp_assoc_t assoc_id;
|
||||
int x2_id;
|
||||
} NR_HANDOVER_INFO;
|
||||
|
||||
#define NR_RRC_BUFFER_SIZE sizeof(RRC_BUFFER_NR)
|
||||
@@ -285,6 +289,7 @@ typedef struct gNB_RRC_UE_s {
|
||||
uint64_t amf_ue_ngap_id;
|
||||
nr_rrc_guami_t ue_guami;
|
||||
|
||||
xnap_security_capabilities_t xnap_security_capabilities;
|
||||
ngap_security_capabilities_t security_capabilities;
|
||||
//NSA block
|
||||
/* Number of NSA e_rab */
|
||||
@@ -324,6 +329,7 @@ typedef struct rrc_gNB_ue_context_s {
|
||||
/* UE id for initial connection to NGAP */
|
||||
struct gNB_RRC_UE_s ue_context;
|
||||
} rrc_gNB_ue_context_t;
|
||||
////why did you change this?? we need to think if it is really needed before taking the code from LTE especially in such common files. I am reverting it back for now. willadd if needed.
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -383,6 +389,12 @@ typedef struct nr_rrc_cuup_container_t {
|
||||
sctp_assoc_t assoc_id;
|
||||
} nr_rrc_cuup_container_t;
|
||||
|
||||
typedef struct nr_xnap_container_t {
|
||||
RB_ENTRY(nr_xnap_container_t) entries;
|
||||
xnap_setup_req_t *setup_req;
|
||||
sctp_assoc_t assoc_id;
|
||||
} nr_xnap_container_t;
|
||||
|
||||
//---NR---(completely change)---------------------
|
||||
typedef struct gNB_RRC_INST_s {
|
||||
|
||||
@@ -405,6 +417,9 @@ typedef struct gNB_RRC_INST_s {
|
||||
|
||||
char *uecap_file;
|
||||
|
||||
// Neighborouring cells id
|
||||
int num_nr_neigh_cells;
|
||||
uint32_t nr_neigh_cells_id[MAX_NUM_NR_NEIGH_CELLs];
|
||||
// security configuration (preferred algorithms)
|
||||
nr_security_configuration_t security;
|
||||
|
||||
@@ -417,6 +432,14 @@ typedef struct gNB_RRC_INST_s {
|
||||
RB_HEAD(rrc_cuup_tree, nr_rrc_cuup_container_t) cuups; // CU-UPs, indexed by assoc_id
|
||||
size_t num_cuups;
|
||||
|
||||
RB_HEAD(xnap_tree, nr_xnap_container_t) xnapids; // XNAP IDs, indexed by assoc_id
|
||||
size_t num_xnapids;
|
||||
|
||||
/* KgNB as computed from parameters within USIM card */
|
||||
uint8_t kgnb[32];
|
||||
uint8_t nh[32];
|
||||
int8_t nh_ncc;
|
||||
|
||||
} gNB_RRC_INST;
|
||||
|
||||
#include "nr_rrc_proto.h" //should be put here otherwise compilation error
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
#include "NR_CG-ConfigInfo.h"
|
||||
#include "NR_SecurityConfig.h"
|
||||
#include "NR_CellGroupConfig.h"
|
||||
// #include "NR_MeasurementReport-IEs.h"
|
||||
#include "NR_MeasurementReport.h"
|
||||
|
||||
#define NR_MAX_SUPPORTED_DL_LAYERS 2
|
||||
|
||||
@@ -135,6 +137,23 @@ void bearer_context_setup_direct(e1ap_bearer_setup_req_t *req,
|
||||
void bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *req,
|
||||
instance_t instance);
|
||||
|
||||
void
|
||||
rrc_gNB_process_MeasurementReport(
|
||||
rrc_gNB_ue_context_t *ue_context, NR_MeasurementReport_t *measurementReport
|
||||
// const protocol_ctxt_t *const ctxt_pP,
|
||||
// rrc_gNB_ue_context_t *ue_context_pP,
|
||||
// const NR_MeasResults_t *const measResults2
|
||||
);
|
||||
|
||||
void
|
||||
rrc_gNB_generate_HandoverPreparationInformation(
|
||||
//const protocol_ctxt_t* const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
uint8_t *buffer,
|
||||
int *_size
|
||||
//LTE_PhysCellId_t targetPhyId
|
||||
);
|
||||
|
||||
void ue_cxt_mod_send_e1ap(MessageDef *msg,
|
||||
instance_t instance);
|
||||
|
||||
|
||||
@@ -97,11 +97,16 @@
|
||||
#include "openair2/F1AP/f1ap_common.h"
|
||||
#include "openair2/F1AP/f1ap_ids.h"
|
||||
#include "openair2/SDAP/nr_sdap/nr_sdap_entity.h"
|
||||
#include "cmake_targets/ran_build/build/openair2/RRC/NR/MESSAGES/NR_HandoverPreparationInformation.h"
|
||||
#include "cmake_targets/ran_build/build/openair2/RRC/NR/MESSAGES/NR_UERadioAccessCapabilityInformation-IEs.h"
|
||||
#include "cucp_cuup_if.h"
|
||||
|
||||
#include "BIT_STRING.h"
|
||||
#include "assertions.h"
|
||||
|
||||
/*Imran*/
|
||||
#include "NR_MeasurementReport-IEs.h"
|
||||
#include <openair2/XNAP/xnap_gNB_task.h>
|
||||
//#include <openair2/COMMON/xnap_messages_types.h>
|
||||
//#define XER_PRINT
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
@@ -1352,7 +1357,20 @@ static inline uint64_t bitStr_to_uint64(const BIT_STRING_t *asn) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static void rrc_gNB_process_MeasurementReport(rrc_gNB_ue_context_t *ue_context, NR_MeasurementReport_t *measurementReport)
|
||||
void rrc_gNB_process_HandoverPreparationInformation(
|
||||
rrc_gNB_ue_context_t *ue_context_p,
|
||||
uint8_t *buffer,
|
||||
int *size)
|
||||
{
|
||||
memset(buffer, 0, 8192);
|
||||
char *ho_buf = (char *) buffer;
|
||||
int ho_size;
|
||||
ho_size = do_NRHandoverPreparation(ho_buf, 8192, ue_context_p->ue_context.UE_Capability_nr, ue_context_p->ue_context.UE_Capability_size);
|
||||
*size = ho_size;
|
||||
}
|
||||
|
||||
|
||||
void rrc_gNB_process_MeasurementReport(rrc_gNB_ue_context_t *ue_context_p, NR_MeasurementReport_t *measurementReport)
|
||||
{
|
||||
if (LOG_DEBUGFLAG(DEBUG_ASN1))
|
||||
xer_fprint(stdout, &asn_DEF_NR_MeasurementReport, (void *)measurementReport);
|
||||
@@ -1360,16 +1378,157 @@ static void rrc_gNB_process_MeasurementReport(rrc_gNB_ue_context_t *ue_context,
|
||||
DevAssert(measurementReport->criticalExtensions.present == NR_MeasurementReport__criticalExtensions_PR_measurementReport
|
||||
&& measurementReport->criticalExtensions.choice.measurementReport != NULL);
|
||||
|
||||
gNB_RRC_UE_t *ue_ctxt = &ue_context->ue_context;
|
||||
gNB_RRC_UE_t *ue_ctxt = &ue_context_p->ue_context;
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_MeasResults, ue_ctxt->measResults);
|
||||
ue_ctxt->measResults = NULL;
|
||||
|
||||
const NR_MeasId_t id = measurementReport->criticalExtensions.choice.measurementReport->measResults.measId;
|
||||
/*Imran*/
|
||||
NR_MeasurementReport_IEs_t *measurementReport_IEs = measurementReport->criticalExtensions.choice.measurementReport;
|
||||
NR_MeasResults_t *ik_measResults = &measurementReport_IEs->measResults;
|
||||
|
||||
AssertFatal(id, "unexpected MeasResult for MeasurementId %ld received\n", id);
|
||||
asn1cCallocOne(ue_ctxt->measResults, measurementReport->criticalExtensions.choice.measurementReport->measResults);
|
||||
/* we "keep" the measurement report, so set to 0 */
|
||||
free(measurementReport->criticalExtensions.choice.measurementReport);
|
||||
measurementReport->criticalExtensions.choice.measurementReport = NULL;
|
||||
bool trigger_ho = false;
|
||||
|
||||
switch (id) {
|
||||
case NR_EventTriggerConfig__eventId_PR_eventA1:
|
||||
LOG_I(NR_RRC, "Event A1 (Serving becomes better than threshold)\n");
|
||||
break;
|
||||
|
||||
case NR_EventTriggerConfig__eventId_PR_eventA2:
|
||||
LOG_I(NR_RRC, "Event A2 (Serving becomes worse than threshold)\n");
|
||||
break;
|
||||
|
||||
case NR_EventTriggerConfig__eventId_PR_eventA3:
|
||||
|
||||
LOG_I(NR_RRC, "Event A3 (Neighbour becomes offset better than SpCell)\n");
|
||||
|
||||
/*Event A3*/
|
||||
/*ServingCell*/
|
||||
/*iterate over all the Cells*/
|
||||
for (int res_mo_idx = 0 ; res_mo_idx < ik_measResults->measResultServingMOList.list.count; res_mo_idx++){
|
||||
|
||||
/*Primary Cells*/
|
||||
|
||||
NR_MeasResultServMO_t *measresultservmo_all = ik_measResults->measResultServingMOList.list.array[res_mo_idx];
|
||||
NR_MeasQuantityResults_t *mqr_all = NULL;
|
||||
|
||||
if (measresultservmo_all->measResultServingCell.measResult.cellResults.resultsSSB_Cell){
|
||||
mqr_all = measresultservmo_all->measResultServingCell.measResult.cellResults.resultsSSB_Cell;
|
||||
}
|
||||
else {
|
||||
mqr_all = measresultservmo_all->measResultServingCell.measResult.cellResults.resultsCSI_RS_Cell;
|
||||
}
|
||||
AssertFatal(mqr_all, "No Serving Cell Measrements!\n");
|
||||
|
||||
const long active_rsrp = *mqr_all->rsrp;
|
||||
const long active_rsrq = *mqr_all->rsrq;
|
||||
LOG_D(RRC, "Serving Cell Measurements: RSRP: %ld dBm, RSRQ: %ld dB\n", active_rsrp, active_rsrq);
|
||||
|
||||
/*Best Neighbour Cell*/
|
||||
|
||||
NR_MeasQuantityResults_t *neighbour_mqr_all = NULL;
|
||||
|
||||
if (measresultservmo_all->measResultServingCell.measResult.cellResults.resultsSSB_Cell){
|
||||
neighbour_mqr_all = measresultservmo_all->measResultBestNeighCell->measResult.cellResults.resultsSSB_Cell;
|
||||
}
|
||||
else {
|
||||
neighbour_mqr_all = measresultservmo_all->measResultBestNeighCell->measResult.cellResults.resultsCSI_RS_Cell;
|
||||
}
|
||||
AssertFatal(neighbour_mqr_all, "No Serving Cell Measrements!\n");
|
||||
|
||||
const long neighbour_rsrp = *neighbour_mqr_all->rsrp;
|
||||
const long neighbour_rsrq = *neighbour_mqr_all->rsrq;
|
||||
LOG_D(RRC, "Best Neighbour Cell Measurements: RSRP: %ld dBm, RSRQ: %ld dB\n", neighbour_rsrp, neighbour_rsrq);
|
||||
|
||||
/*Offset for now considering 0*/
|
||||
|
||||
if (neighbour_rsrp > active_rsrp){
|
||||
trigger_ho = true;
|
||||
|
||||
/*HO Initiation*/
|
||||
}
|
||||
}
|
||||
case NR_EventTriggerConfig__eventId_PR_eventA4:
|
||||
LOG_I(NR_RRC, "Event A4 (Neighbour becomes better than threshold)\n");
|
||||
break;
|
||||
|
||||
case NR_EventTriggerConfig__eventId_PR_eventA5:
|
||||
LOG_I(NR_RRC, "Event A5 (SpCell becomes worse than threshold1 and neighbour becomes better than threshold2)\n");
|
||||
break;
|
||||
|
||||
case NR_EventTriggerConfig__eventId_PR_eventA6:
|
||||
LOG_I(NR_RRC, "Event A6 (Neighbour becomes offset better than SCell)\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_I(NR_RRC, "NR_EventTriggerConfig__eventId_PR_NOTHING or Other event report\n");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (trigger_ho == true) {
|
||||
LOG_I(NR_RRC, "Handover is triggered\n");
|
||||
}
|
||||
|
||||
NR_MeasResultServMO_t *measresultservmo = ik_measResults->measResultServingMOList.list.array[0]; //getting only first
|
||||
NR_MeasResultNR_t *measresultnr = &measresultservmo->measResultServingCell;
|
||||
NR_MeasQuantityResults_t *mqr = measresultnr->measResult.cellResults.resultsSSB_Cell;
|
||||
// int ncell_index=0;
|
||||
|
||||
if (mqr != NULL){
|
||||
const long rrsrp = *mqr->rsrp - 156;
|
||||
const float rrsrq = (float) (*mqr->rsrq - 87) / 2.0f;
|
||||
const float rsinr = (float) (*mqr->sinr - 46) / 2.0f;
|
||||
LOG_D(RRC, "RSRP %ld dBm RSRQ %.1f dB SINR %.1f dB\n", rrsrp, rrsrq, rsinr);
|
||||
}
|
||||
/** Handling of Neighborcells has to be done here **/
|
||||
if (!ue_ctxt->measResults->measResultNeighCells) {
|
||||
ue_ctxt->measResults->measResultNeighCells = calloc(1,sizeof(*ue_ctxt->measResults->measResultNeighCells));
|
||||
ue_ctxt->measResults->measResultNeighCells->present = NR_MeasResults__measResultNeighCells_PR_measResultListNR;
|
||||
ue_ctxt->measResults->measResultNeighCells->choice.measResultListNR->list.array = calloc(1, sizeof(*ue_ctxt->measResults->measResultNeighCells->choice.measResultListNR->list.array));
|
||||
ue_ctxt->measResults->measResultNeighCells->choice.measResultListNR->list.array[0] = calloc(1, sizeof(*ue_ctxt->measResults->measResultNeighCells->choice.measResultListNR->list.array[0]));
|
||||
ue_ctxt->measResults->measResultNeighCells->choice.measResultListNR->list.count = 1;
|
||||
}
|
||||
|
||||
LOG_D(RRC, "NR MeasID %ld\n", id);
|
||||
|
||||
/*ALL NeighbourCell*/
|
||||
// NR_MeasResultNR_t *neighbour_measresult = ik_measResults->measResultNeighCells->choice.measResultListNR->list.array[0] ; /* Need to review this whether to retain */
|
||||
|
||||
/*Imran*/
|
||||
// MessageDef *msg;
|
||||
//int ncell_index=0;
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, XNAP_HANDOVER_REQ);
|
||||
|
||||
/* Need to add function to get best neighbour cells */
|
||||
rrc_gNB_process_HandoverPreparationInformation(
|
||||
ue_context_p,
|
||||
// xnap_msg); /////first arguement is a type ////where is xnap_msg defined?
|
||||
XNAP_HANDOVER_REQ(msg).ue_context.rrc_buffer,
|
||||
&XNAP_HANDOVER_REQ(msg).ue_context.rrc_buffer_size);
|
||||
|
||||
XNAP_HANDOVER_REQ(msg).target_cgi.cgi = ue_ctxt->measResults->measResultNeighCells->choice.measResultListNR->list.array[0]->physCellId;//hardcoded to 0 , confirm if its phy cell id only, add plmn-mcc,mnc
|
||||
// XNAP_HANDOVER_REQ(msg).target_cgi.cgi = ue_ctxt->measResults->measResultNeighCells->choice.
|
||||
|
||||
XNAP_HANDOVER_REQ(msg).guami.plmn_id.mcc = ue_ctxt->ue_guami.mcc;
|
||||
XNAP_HANDOVER_REQ(msg).guami.plmn_id.mnc = ue_ctxt->ue_guami.mnc;
|
||||
XNAP_HANDOVER_REQ(msg).guami.plmn_id.mnc_digit_length = ue_ctxt->ue_guami.mnc_len;
|
||||
XNAP_HANDOVER_REQ(msg).guami.amf_region_id = ue_ctxt->ue_guami.amf_region_id;
|
||||
XNAP_HANDOVER_REQ(msg).guami.amf_set_id = ue_ctxt->ue_guami.amf_set_id;
|
||||
XNAP_HANDOVER_REQ(msg).guami.amf_pointer = ue_ctxt->ue_guami.amf_pointer;
|
||||
XNAP_HANDOVER_REQ(msg).ue_context.security_capabilities = ue_ctxt->xnap_security_capabilities;
|
||||
// compute kgNB*
|
||||
// Need to add kgNB computation
|
||||
|
||||
nr_derive_key(RRC_ENC_ALG, ue_ctxt->ciphering_algorithm, ue_ctxt->kgnb,XNAP_HANDOVER_REQ(msg).ue_context.kRRCenc); //need to review this again whether kgNB key has to be generated
|
||||
nr_derive_key(RRC_INT_ALG, ue_ctxt->integrity_algorithm, ue_ctxt->kgnb,XNAP_HANDOVER_REQ(msg).ue_context. kRRCint);
|
||||
|
||||
// XNAP_HANDOVER_REQ(msg).kenb_ncc = ue_context_pP->ue_context.kenb_ncc;
|
||||
// XNAP_HANDOVER_REQ(msg).ue_context.nb_e_rabs_tobesetup = ue_ctxt->ue_context.nb_of_e_rabs;
|
||||
itti_send_msg_to_task(TASK_XNAP, 0, msg);
|
||||
////send to TASK_XNAP
|
||||
}
|
||||
|
||||
static int handle_rrcReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP,
|
||||
@@ -1676,7 +1835,7 @@ int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP,
|
||||
DevAssert(ul_dcch_msg != NULL
|
||||
&& ul_dcch_msg->message.present == NR_UL_DCCH_MessageType_PR_c1
|
||||
&& ul_dcch_msg->message.choice.c1
|
||||
&& ul_dcch_msg->message.choice.c1->present == NR_UL_DCCH_MessageType__c1_PR_measurementReport);
|
||||
&& ul_dcch_msg->message.choice.c1->present == NR_UL_DCCH_MessageType__c1_PR_measurementReport);////why these checks are needed? arent they redundant?
|
||||
rrc_gNB_process_MeasurementReport(ue_context_p, ul_dcch_msg->message.choice.c1->choice.measurementReport);
|
||||
break;
|
||||
|
||||
@@ -2182,6 +2341,38 @@ void rrc_gNB_process_e1_bearer_context_release_cplt(const e1ap_bearer_release_cp
|
||||
LOG_I(RRC, "UE %d: received bearer release complete\n", cplt->gNB_cu_cp_ue_id);
|
||||
}
|
||||
|
||||
void rrc_gNB_process_xn_setup_request(sctp_assoc_t assoc_id, xnap_setup_req_t *m)
|
||||
{
|
||||
if (RC.nrrrc[0]->num_nr_neigh_cells > MAX_NUM_NR_NEIGH_CELLs) {
|
||||
LOG_E(NR_RRC, "Error: number of neighbouring cells is exceeded \n");
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, XNAP_SETUP_FAILURE);
|
||||
msg->ittiMsgHeader.originInstance = assoc_id;
|
||||
xnap_setup_failure_t *xnap_msg = &XNAP_SETUP_FAILURE(msg);
|
||||
xnap_msg->cause_type = XNAP_CAUSE_PROTOCOL;
|
||||
xnap_msg->cause_value = 6; //XNAP_CauseProtocol_unspecified;
|
||||
itti_send_msg_to_task(TASK_XNAP, 0, msg);
|
||||
}
|
||||
|
||||
RC.nrrrc[0]->num_nr_neigh_cells++;
|
||||
RC.nrrrc[0]->nr_neigh_cells_id[RC.nrrrc[0]->num_nr_neigh_cells - 1] = m->info.nr_pci;
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, XNAP_SETUP_RESP);
|
||||
msg->ittiMsgHeader.originInstance = assoc_id;
|
||||
xnap_setup_resp_t *xnap_msg = &XNAP_SETUP_RESP(msg);
|
||||
xnap_msg->gNB_id = m->gNB_id;
|
||||
xnap_msg->info = m->info;//add all required
|
||||
itti_send_msg_to_task(TASK_XNAP, 0, msg);
|
||||
}
|
||||
|
||||
void rrc_gNB_process_xn_setup_response(sctp_assoc_t assoc_id, xnap_setup_resp_t *m)
|
||||
{
|
||||
if (RC.nrrrc[0]->num_nr_neigh_cells > MAX_NUM_NR_NEIGH_CELLs) {
|
||||
LOG_E(RRC, "Error: number of neighbouring cells is exceeded \n");
|
||||
return;
|
||||
}
|
||||
RC.nrrrc[0]->num_nr_neigh_cells++;
|
||||
RC.nrrrc[0]->nr_neigh_cells_id[RC.nrrrc[0]->num_nr_neigh_cells - 1] = m->info.nr_pci;
|
||||
}
|
||||
|
||||
static void print_rrc_meas(FILE *f, const NR_MeasResults_t *measresults)
|
||||
{
|
||||
DevAssert(measresults->measResultServingMOList.list.count >= 1);
|
||||
@@ -2301,7 +2492,7 @@ void *rrc_gnb_task(void *args_p) {
|
||||
/* timer to write stats to file */
|
||||
timer_setup(1, 0, TASK_RRC_GNB, 0, TIMER_PERIODIC, NULL, &stats_timer_id);
|
||||
}
|
||||
|
||||
|
||||
itti_mark_task_ready(TASK_RRC_GNB);
|
||||
LOG_I(NR_RRC,"Entering main loop of NR_RRC message task\n");
|
||||
|
||||
@@ -2405,6 +2596,15 @@ void *rrc_gnb_task(void *args_p) {
|
||||
rrc_CU_process_f1_lost_connection(RC.nrrrc[0], &F1AP_LOST_CONNECTION(msg_p), msg_p->ittiMsgHeader.originInstance);
|
||||
break;
|
||||
|
||||
/*Messages from XNAP*/
|
||||
case XNAP_SETUP_RESP:
|
||||
rrc_gNB_process_xn_setup_response(ITTI_MSG_ORIGIN_INSTANCE(msg_p), &XNAP_SETUP_RESP(msg_p));
|
||||
break;
|
||||
|
||||
case XNAP_SETUP_REQ:
|
||||
rrc_gNB_process_xn_setup_request(ITTI_MSG_ORIGIN_INSTANCE(msg_p), &XNAP_SETUP_REQ(msg_p));
|
||||
break;
|
||||
|
||||
/* Messages from X2AP */
|
||||
case X2AP_ENDC_SGNB_ADDITION_REQ:
|
||||
LOG_I(NR_RRC, "Received ENDC sgNB addition request from X2AP \n");
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
add_subdirectory(MESSAGES)
|
||||
add_library(xnap xnap_common.c)
|
||||
add_library(xnap
|
||||
xnap_common.c
|
||||
xnap_gNB_task.c
|
||||
xnap_gNB_management_procedures.c
|
||||
xnap_gNB_itti_messaging.c
|
||||
xnap_gNB_handler.c
|
||||
xnap_gNB_interface_management.c
|
||||
xnap_timers.c
|
||||
xnap_gNB_generate_messages.c
|
||||
xnap_ids.c)
|
||||
target_link_libraries(xnap
|
||||
PUBLIC asn1_xnap
|
||||
PRIVATE nr_rrc)
|
||||
|
||||
@@ -19,30 +19,56 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file xnap_common.c
|
||||
* \brief xnap encoder,decoder dunctions for gNB
|
||||
* \author Sreeshma Shiv <sreeshmau@iisc.ac.in>
|
||||
* \date Dec 2023
|
||||
* \version 1.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
#include "intertask_interface.h"
|
||||
#include "xnap_common.h"
|
||||
#include "XNAP_XnAP-PDU.h"
|
||||
|
||||
ssize_t XNAP_generate_initiating_message(uint8_t **buffer,
|
||||
uint32_t *length,
|
||||
XNAP_ProcedureCode_t procedureCode,
|
||||
XNAP_Criticality_t criticality,
|
||||
asn_TYPE_descriptor_t *td,
|
||||
void *sptr)
|
||||
int xnap_gNB_encode_pdu(XNAP_XnAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len)
|
||||
{
|
||||
XNAP_XnAP_PDU_t pdu;
|
||||
ssize_t encoded;
|
||||
memset(&pdu, 0, sizeof(XNAP_XnAP_PDU_t));
|
||||
pdu.present = XNAP_XnAP_PDU_PR_initiatingMessage;
|
||||
pdu.choice.initiatingMessage->procedureCode = procedureCode;
|
||||
pdu.choice.initiatingMessage->criticality = criticality;
|
||||
ANY_fromType_aper((ANY_t *)&pdu.choice.initiatingMessage->value, td, sptr);
|
||||
|
||||
if ((encoded = aper_encode_to_new_buffer(&asn_DEF_XNAP_XnAP_PDU, 0, &pdu, (void **)buffer)) < 0) {
|
||||
DevAssert(pdu != NULL);
|
||||
DevAssert(buffer != NULL);
|
||||
DevAssert(len != NULL);
|
||||
|
||||
xer_fprint(stdout, &asn_DEF_XNAP_XnAP_PDU, (void *)pdu);
|
||||
|
||||
encoded = aper_encode_to_new_buffer(&asn_DEF_XNAP_XnAP_PDU, 0, pdu, (void **)buffer);
|
||||
|
||||
if (encoded < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*length = encoded;
|
||||
*len = encoded;
|
||||
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_XNAP_XnAP_PDU, pdu);
|
||||
return encoded;
|
||||
}
|
||||
|
||||
int xnap_gNB_decode_pdu(XNAP_XnAP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length)
|
||||
{
|
||||
asn_dec_rval_t dec_ret;
|
||||
|
||||
DevAssert(buffer != NULL);
|
||||
|
||||
dec_ret = aper_decode(NULL, &asn_DEF_XNAP_XnAP_PDU, (void **)&pdu, buffer, length, 0, 0);
|
||||
xer_fprint(stdout, &asn_DEF_XNAP_XnAP_PDU, pdu);
|
||||
if (dec_ret.code != RC_OK) {
|
||||
LOG_E(XNAP, "Failed to decode PDU\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
/* 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
|
||||
* 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
|
||||
*
|
||||
* Author and copyright: Laurent Thomas, open-cells.com
|
||||
*
|
||||
* 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.
|
||||
@@ -23,22 +20,26 @@
|
||||
|
||||
#ifndef XNAP_COMMON_H_
|
||||
#define XNAP_COMMON_H_
|
||||
|
||||
#include "XNAP_XnAP-PDU.h"
|
||||
#include "intertask_interface.h"
|
||||
#include "common/openairinterface5g_limits.h"
|
||||
#include "oai_asn1.h"
|
||||
#include "XNAP_ProtocolIE-Field.h"
|
||||
#include "XNAP_InitiatingMessage.h"
|
||||
#include "XNAP_ProtocolIE-ContainerPair.h"
|
||||
#include "XNAP_ProtocolExtensionField.h"
|
||||
#include "XNAP_ProtocolExtensionContainer.h"
|
||||
#include "XNAP_ProtocolExtensionField.h"
|
||||
#include "XNAP_ProtocolIE-ContainerPair.h"
|
||||
#include "XNAP_ProtocolIE-Field.h"
|
||||
#include "XNAP_ProtocolIE-FieldPair.h"
|
||||
#include "XNAP_SuccessfulOutcome.h"
|
||||
#include "XNAP_UnsuccessfulOutcome.h"
|
||||
#include "XNAP_XnAP-PDU.h"
|
||||
#include "XNAP_asn_constant.h"
|
||||
#include "common/openairinterface5g_limits.h"
|
||||
#include "intertask_interface.h"
|
||||
#include "oai_asn1.h"
|
||||
|
||||
#ifndef XNAP_PORT
|
||||
#define XNAP_PORT 38422
|
||||
#define XNAP_PORT 38423
|
||||
#endif
|
||||
|
||||
extern int asn1_xer_print;
|
||||
|
||||
#define XNAP_FIND_PROTOCOLIE_BY_ID(IE_TYPE, ie, container, IE_ID, mandatory) \
|
||||
do { \
|
||||
IE_TYPE **ptr; \
|
||||
@@ -54,11 +55,7 @@
|
||||
DevAssert(ie != NULL); \
|
||||
} while (0)
|
||||
|
||||
ssize_t xnap_generate_initiating_message(uint8_t **buffer,
|
||||
uint32_t *length,
|
||||
XNAP_ProcedureCode_t procedureCode,
|
||||
XNAP_Criticality_t criticality,
|
||||
asn_TYPE_descriptor_t *td,
|
||||
void *sptr);
|
||||
|
||||
typedef int (*xnap_message_decoded_callback)(instance_t instance, sctp_assoc_t assocId, uint32_t stream, XNAP_XnAP_PDU_t *pdu);
|
||||
int xnap_gNB_decode_pdu(XNAP_XnAP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length) __attribute__((warn_unused_result));
|
||||
int xnap_gNB_encode_pdu(XNAP_XnAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) __attribute__((warn_unused_result));
|
||||
#endif /* XNAP_COMMON_H_ */
|
||||
|
||||
66
openair2/XNAP/xnap_gNB_decoder.c
Normal file
66
openair2/XNAP/xnap_gNB_decoder.c
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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 xnap_gNB_decoder.c
|
||||
* \date July 2023
|
||||
* \version 1.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "assertions.h"
|
||||
#include "intertask_interface.h"
|
||||
#include "xnap_common.h"
|
||||
#include "xnap_gNB_decoder.h"
|
||||
|
||||
int xnap_gNB_decode_pdu(XNAP_XnAP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length)
|
||||
{
|
||||
asn_dec_rval_t dec_ret;
|
||||
|
||||
DevAssert(buffer != NULL);
|
||||
|
||||
dec_ret = aper_decode(NULL, &asn_DEF_XNAP_XnAP_PDU, (void **)&pdu, buffer, length, 0, 0);
|
||||
xer_fprint(stdout, &asn_DEF_XNAP_XnAP_PDU, pdu);
|
||||
if (dec_ret.code != RC_OK) {
|
||||
LOG_E(XNAP, "Failed to decode PDU\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (pdu->present) {
|
||||
case XNAP_XnAP_PDU_PR_initiatingMessage:
|
||||
LOG_I(XNAP, "xnap_gNB_decode_initiating_message!\n");
|
||||
break;
|
||||
case XNAP_XnAP_PDU_PR_successfulOutcome:
|
||||
LOG_I(XNAP, "xnap_gNB_decode_successfuloutcome_message!\n");
|
||||
break;
|
||||
case XNAP_XnAP_PDU_PR_unsuccessfulOutcome:
|
||||
LOG_I(XNAP, "xnap_gNB_decode_unsuccessfuloutcome_message!\n");
|
||||
break;
|
||||
case XNAP_ProcedureCode_id_handoverPreparation:
|
||||
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_XNAP_XNAP_PDU, pdu);
|
||||
XNAP_INFO("xnap_eNB_decode_initiating_message!\n");
|
||||
break;
|
||||
default:
|
||||
LOG_D(XNAP, "Unknown presence (%d) or not implemented\n", (int)pdu->present);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
33
openair2/XNAP/xnap_gNB_decoder.h
Normal file
33
openair2/XNAP/xnap_gNB_decoder.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 xnap_gNB_decoder.h
|
||||
* \date July 2023
|
||||
* \version 1.0
|
||||
*/
|
||||
|
||||
#ifndef XNAP_GNB_DECODER_H_
|
||||
#define XNAP_GNB_DECODER_H_
|
||||
|
||||
int xnap_gNB_decode_pdu(XNAP_XnAP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length) __attribute__((warn_unused_result));
|
||||
|
||||
#endif /* XNAP_GNB_DECODER_H_ */
|
||||
|
||||
99
openair2/XNAP/xnap_gNB_defs.h
Normal file
99
openair2/XNAP/xnap_gNB_defs.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/* 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 <stdint.h>
|
||||
#include "queue.h"
|
||||
#include "tree.h"
|
||||
#include "sctp_eNB_defs.h"
|
||||
#include "xnap_messages_types.h"
|
||||
#include "xnap_ids.h"
|
||||
#include "xnap_timers.h"
|
||||
|
||||
#ifndef XNAP_GNB_DEFS_H_
|
||||
#define XNAP_GNB_DEFS_H_
|
||||
|
||||
#define XNAP_GNB_NAME_LENGTH_MAX (150)
|
||||
|
||||
typedef enum {
|
||||
/* Disconnected state: initial state for any association. */
|
||||
XNAP_GNB_STATE_DISCONNECTED = 0x0,
|
||||
|
||||
/* State waiting for xn Setup response message if the target gNB accepts or
|
||||
* Xn Setup failure if rejects the gNB.
|
||||
*/
|
||||
XNAP_GNB_STATE_WAITING = 0x1,
|
||||
|
||||
/* The gNB is successfully connected to another gNB. */
|
||||
XNAP_GNB_STATE_CONNECTED = 0x2,
|
||||
|
||||
/* XnAP is ready, and the gNB is successfully connected to another gNB. */
|
||||
XNAP_GNB_STATE_READY = 0x3,
|
||||
|
||||
XNAP_GNB_STATE_OVERLOAD = 0x4,
|
||||
|
||||
XNAP_GNB_STATE_RESETTING = 0x5,
|
||||
|
||||
/* Max number of states available */
|
||||
XNAP_GNB_STATE_MAX,
|
||||
} xnap_gNB_state_t;
|
||||
|
||||
struct xnap_gNB_instance_s;
|
||||
|
||||
/* This structure describes association of gNBs over Xn */
|
||||
typedef struct xnap_gNB_data_t {
|
||||
/* gNB descriptors tree, ordered by sctp assoc id */
|
||||
RB_ENTRY(xnap_gNB_data_t) entry;
|
||||
char *gNB_name;
|
||||
/* target gNB ID */
|
||||
uint64_t gNB_id;
|
||||
/* Current gNB->gNB XnAP association state */
|
||||
xnap_gNB_state_t state;
|
||||
/* Number of input/ouput streams */
|
||||
uint16_t in_streams;
|
||||
uint16_t out_streams;
|
||||
/* Connexion id used between SCTP/XNAP */
|
||||
uint16_t cnx_id;
|
||||
/* SCTP association id */
|
||||
sctp_assoc_t assoc_id;
|
||||
} xnap_gNB_data_t;
|
||||
|
||||
typedef struct xnap_gNB_instance_s {
|
||||
/* Number of target gNBs requested by gNB (tree size) */
|
||||
uint32_t xn_target_gnb_nb;
|
||||
/* Number of target gNBs for which association is pending */
|
||||
uint32_t xn_target_gnb_pending_nb;
|
||||
/* Number of target gNB successfully associated to gNB */
|
||||
uint32_t xn_target_gnb_associated_nb;
|
||||
/* Tree of XNAP gNB associations ordered by association ID */
|
||||
RB_HEAD(xnap_gnb_tree, xnap_gNB_data_t) xnap_gnbs; // gNBs, indexed by assoc_id
|
||||
size_t num_gnbs;
|
||||
instance_t instance;
|
||||
xnap_setup_req_t setup_req;
|
||||
|
||||
/* The gNB IP address to bind */
|
||||
xnap_net_config_t net_config;
|
||||
/* SCTP information */
|
||||
xnap_sctp_t sctp_streams;
|
||||
char *gNB_name;
|
||||
xnap_id_manager id_manager;
|
||||
xnap_timers_t timers;
|
||||
} xnap_gNB_instance_t;
|
||||
|
||||
#endif /* XNAP_GNB_DEFS_H_ */
|
||||
59
openair2/XNAP/xnap_gNB_encoder.c
Normal file
59
openair2/XNAP/xnap_gNB_encoder.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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 xnap_gNB_encoder.c
|
||||
* \brief xnap encoder procedures for gNB
|
||||
* \author Sreeshma Shiv <sreeshmau@iisc.ac.in>
|
||||
* \date August 2023
|
||||
* \version 1.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
#include "intertask_interface.h"
|
||||
#include "xnap_common.h"
|
||||
#include "xnap_gNB_encoder.h"
|
||||
|
||||
int xnap_gNB_encode_pdu(XNAP_XnAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len)
|
||||
{
|
||||
ssize_t encoded;
|
||||
|
||||
DevAssert(pdu != NULL);
|
||||
DevAssert(buffer != NULL);
|
||||
DevAssert(len != NULL);
|
||||
|
||||
xer_fprint(stdout, &asn_DEF_XNAP_XnAP_PDU, (void *)pdu);
|
||||
|
||||
encoded = aper_encode_to_new_buffer(&asn_DEF_XNAP_XnAP_PDU, 0, pdu, (void **)buffer);
|
||||
|
||||
if (encoded < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*len = encoded;
|
||||
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_XNAP_XnAP_PDU, pdu);
|
||||
return encoded;
|
||||
}
|
||||
33
openair2/XNAP/xnap_gNB_encoder.h
Normal file
33
openair2/XNAP/xnap_gNB_encoder.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 xnap_gNB_encoder.h
|
||||
* \brief xnap encoder procedures for gNB
|
||||
* \date July 2023
|
||||
* \version 1.0
|
||||
*/
|
||||
|
||||
#ifndef XNAP_GNB_ENCODER_H_
|
||||
#define XNAP_GNB_ENCODER_H_
|
||||
|
||||
int xnap_gNB_encode_pdu(XNAP_XnAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) __attribute__((warn_unused_result));
|
||||
|
||||
#endif /* XNAP_GNB_ENCODER_H_ */
|
||||
930
openair2/XNAP/xnap_gNB_generate_messages.c
Normal file
930
openair2/XNAP/xnap_gNB_generate_messages.c
Normal file
@@ -0,0 +1,930 @@
|
||||
/* 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 "intertask_interface.h"
|
||||
#include "xnap_common.h"
|
||||
#include "xnap_gNB_task.h"
|
||||
#include "xnap_gNB_generate_messages.h"
|
||||
#include "XNAP_ProtocolIE-Field.h"
|
||||
#include "XNAP_GlobalgNB-ID.h"
|
||||
#include "XNAP_ServedCells-NR-Item.h"
|
||||
#include "XNAP_ServedCellInformation-NR.h"
|
||||
#include "XNAP_NRFrequencyBandItem.h"
|
||||
#include "xnap_gNB_itti_messaging.h"
|
||||
#include "XNAP_ServedCells-NR.h"
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
#include "XNAP_BroadcastPLMNinTAISupport-Item.h"
|
||||
#include "XNAP_TAISupport-Item.h"
|
||||
#include "XNAP_GlobalAMF-Region-Information.h"
|
||||
#include "XNAP_TargetCellList-Item.h"
|
||||
#include "XNAP_GlobalAMF-Region-Information.h"
|
||||
#include "XNAP_QoSFlowsToBeSetup-Item.h"
|
||||
#include "XNAP_NRModeInfoFDD.h"
|
||||
#include "XNAP_NRModeInfoTDD.h"
|
||||
#include "openair2/RRC/NR/nr_rrc_defs.h"
|
||||
#include "xnap_gNB_defs.h"
|
||||
|
||||
int xnap_gNB_generate_xn_setup_request(sctp_assoc_t assoc_id, xnap_setup_req_t *req)
|
||||
{
|
||||
XNAP_XnAP_PDU_t pdu;
|
||||
XNAP_XnSetupRequest_t *out;
|
||||
XNAP_XnSetupRequest_IEs_t *ie;
|
||||
XNAP_BroadcastPLMNinTAISupport_Item_t *e_BroadcastPLMNinTAISupport_ItemIE;
|
||||
XNAP_TAISupport_Item_t *TAISupport_ItemIEs;
|
||||
XNAP_S_NSSAI_t *e_S_NSSAI_ItemIE;
|
||||
XNAP_GlobalAMF_Region_Information_t *e_GlobalAMF_Region_Information_ItemIEs;
|
||||
XNAP_ServedCells_NR_Item_t *servedCellMember;
|
||||
XNAP_NRFrequencyBandItem_t *nrfreqbanditemul;
|
||||
XNAP_NRFrequencyBandItem_t *nrfreqbanditemdl;
|
||||
XNAP_NRFrequencyBandItem_t *nrfreqbanditem;
|
||||
XNAP_PLMN_Identity_t *plmn;
|
||||
|
||||
uint8_t *buffer;
|
||||
uint32_t len;
|
||||
int ret = 0;
|
||||
|
||||
/* Prepare the XnAP message to encode */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
|
||||
pdu.present = XNAP_XnAP_PDU_PR_initiatingMessage;
|
||||
// pdu.choice.initiatingMessage = &initiating_msg;
|
||||
pdu.choice.initiatingMessage = (XNAP_InitiatingMessage_t *)calloc(1, sizeof(XNAP_InitiatingMessage_t));
|
||||
pdu.choice.initiatingMessage->procedureCode = XNAP_ProcedureCode_id_xnSetup;
|
||||
pdu.choice.initiatingMessage->criticality = XNAP_Criticality_reject;
|
||||
pdu.choice.initiatingMessage->value.present = XNAP_InitiatingMessage__value_PR_XnSetupRequest;
|
||||
|
||||
out = &pdu.choice.initiatingMessage->value.choice.XnSetupRequest;
|
||||
|
||||
/* mandatory */
|
||||
ie = (XNAP_XnSetupRequest_IEs_t *)calloc(1, sizeof(XNAP_XnSetupRequest_IEs_t));
|
||||
ie->id = XNAP_ProtocolIE_ID_id_GlobalNG_RAN_node_ID;
|
||||
ie->criticality = XNAP_Criticality_reject;
|
||||
ie->value.present = XNAP_XnSetupRequest_IEs__value_PR_GlobalNG_RANNode_ID;
|
||||
ie->value.choice.GlobalNG_RANNode_ID.present = XNAP_GlobalNG_RANNode_ID_PR_gNB;
|
||||
ie->value.choice.GlobalNG_RANNode_ID.choice.gNB = (XNAP_GlobalgNB_ID_t *)calloc(1, sizeof(XNAP_GlobalgNB_ID_t));
|
||||
MCC_MNC_TO_PLMNID(req->info.plmn.mcc,
|
||||
req->info.plmn.mnc,
|
||||
req->info.plmn.mnc_digit_length,
|
||||
&ie->value.choice.GlobalNG_RANNode_ID.choice.gNB->plmn_id);
|
||||
|
||||
ie->value.choice.GlobalNG_RANNode_ID.choice.gNB->gnb_id.present = XNAP_GNB_ID_Choice_PR_gnb_ID;
|
||||
|
||||
MACRO_GNB_ID_TO_BIT_STRING(req->gNB_id, &ie->value.choice.GlobalNG_RANNode_ID.choice.gNB->gnb_id.choice.gnb_ID); // 28 bits
|
||||
LOG_I(XNAP,
|
||||
"%lu -> %02x%02x%02x\n",
|
||||
req->gNB_id,
|
||||
ie->value.choice.GlobalNG_RANNode_ID.choice.gNB->gnb_id.choice.gnb_ID.buf[0],
|
||||
ie->value.choice.GlobalNG_RANNode_ID.choice.gNB->gnb_id.choice.gnb_ID.buf[1],
|
||||
ie->value.choice.GlobalNG_RANNode_ID.choice.gNB->gnb_id.choice.gnb_ID.buf[2]);
|
||||
|
||||
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
||||
|
||||
/* mandatory */ // TAI Support list
|
||||
ie = (XNAP_XnSetupRequest_IEs_t *)calloc(1, sizeof(XNAP_XnSetupRequest_IEs_t));
|
||||
ie->id = XNAP_ProtocolIE_ID_id_TAISupport_list;
|
||||
ie->criticality = XNAP_Criticality_reject;
|
||||
ie->value.present = XNAP_XnSetupRequest_IEs__value_PR_TAISupport_List;
|
||||
|
||||
// for (int i=0;i<1;i++)
|
||||
{
|
||||
TAISupport_ItemIEs = (XNAP_TAISupport_Item_t *)calloc(1, sizeof(XNAP_TAISupport_Item_t));
|
||||
INT24_TO_OCTET_STRING(req->tai_support, &TAISupport_ItemIEs->tac);
|
||||
{
|
||||
for (int j = 0; j < 1; j++) {
|
||||
e_BroadcastPLMNinTAISupport_ItemIE =
|
||||
(XNAP_BroadcastPLMNinTAISupport_Item_t *)calloc(1, sizeof(XNAP_BroadcastPLMNinTAISupport_Item_t));
|
||||
|
||||
MCC_MNC_TO_PLMNID(req->info.plmn.mcc,
|
||||
req->info.plmn.mnc,
|
||||
req->info.plmn.mnc_digit_length,
|
||||
&e_BroadcastPLMNinTAISupport_ItemIE->plmn_id);
|
||||
|
||||
for (int k = 0; k < 1; k++) {
|
||||
e_S_NSSAI_ItemIE = (XNAP_S_NSSAI_t *)calloc(1, sizeof(XNAP_S_NSSAI_t));
|
||||
INT8_TO_OCTET_STRING(req->snssai[k].sst, &e_S_NSSAI_ItemIE->sst);
|
||||
if (req->snssai[k].sd != 0xffffff && req->snssai[k].sd != 0) {
|
||||
e_S_NSSAI_ItemIE->sd = calloc(3, sizeof(OCTET_STRING_t));
|
||||
INT24_TO_OCTET_STRING(req->snssai[k].sd, e_S_NSSAI_ItemIE->sd);
|
||||
}
|
||||
asn1cSeqAdd(&e_BroadcastPLMNinTAISupport_ItemIE->tAISliceSupport_List.list, e_S_NSSAI_ItemIE);
|
||||
}
|
||||
asn1cSeqAdd(&TAISupport_ItemIEs->broadcastPLMNs.list, e_BroadcastPLMNinTAISupport_ItemIE);
|
||||
}
|
||||
}
|
||||
asn1cSeqAdd(&ie->value.choice.TAISupport_List.list, TAISupport_ItemIEs);
|
||||
}
|
||||
//}
|
||||
|
||||
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
||||
|
||||
/* mandatory */
|
||||
ie = (XNAP_XnSetupRequest_IEs_t *)calloc(1, sizeof(XNAP_XnSetupRequest_IEs_t));
|
||||
ie->id = XNAP_ProtocolIE_ID_id_List_of_served_cells_NR;
|
||||
ie->criticality = XNAP_Criticality_reject;
|
||||
ie->value.present = XNAP_XnSetupRequest_IEs__value_PR_ServedCells_NR;
|
||||
{
|
||||
servedCellMember = (XNAP_ServedCells_NR_Item_t *)calloc(1, sizeof(XNAP_ServedCells_NR_Item_t));
|
||||
{
|
||||
servedCellMember->served_cell_info_NR.nrPCI = req->info.nr_pci; // long
|
||||
|
||||
MCC_MNC_TO_PLMNID(req->info.plmn.mcc,
|
||||
req->info.plmn.mnc,
|
||||
req->info.plmn.mnc_digit_length,
|
||||
&servedCellMember->served_cell_info_NR.cellID.plmn_id); // octet string
|
||||
NR_CELL_ID_TO_BIT_STRING(req->gNB_id,
|
||||
&servedCellMember->served_cell_info_NR.cellID.nr_CI); // bit string
|
||||
|
||||
INT24_TO_OCTET_STRING(req->tai_support, &servedCellMember->served_cell_info_NR.tac); // octet string
|
||||
for (int k = 0; k < 1; k++) {
|
||||
plmn = (XNAP_PLMN_Identity_t *)calloc(1, sizeof(XNAP_PLMN_Identity_t));
|
||||
{
|
||||
MCC_MNC_TO_PLMNID(req->info.plmn.mcc, req->info.plmn.mnc, req->info.plmn.mnc_digit_length, plmn);
|
||||
asn1cSeqAdd(&servedCellMember->served_cell_info_NR.broadcastPLMN.list, plmn);
|
||||
}
|
||||
}
|
||||
if (req->info.mode == XNAP_MODE_FDD) { // FDD
|
||||
const xnap_fdd_info_t *fdd = &req->info.fdd;
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.present = XNAP_NRModeInfo_PR_fdd;
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd =
|
||||
(XNAP_NRModeInfoFDD_t *)calloc(1, sizeof(XNAP_NRModeInfoFDD_t));
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRFrequencyInfo.nrARFCN = fdd->ul_freqinfo.arfcn;
|
||||
for (int j = 0; j < 1; j++) { // fdd ul number of available freq_Bands = 1
|
||||
nrfreqbanditemul = (XNAP_NRFrequencyBandItem_t *)calloc(1, sizeof(XNAP_NRFrequencyBandItem_t));
|
||||
nrfreqbanditemul->nr_frequency_band = fdd->ul_freqinfo.band;
|
||||
asn1cSeqAdd(&servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRFrequencyInfo.frequencyBand_List.list,
|
||||
nrfreqbanditemul);
|
||||
}
|
||||
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRFrequencyInfo.nrARFCN = fdd->dl_freqinfo.arfcn;
|
||||
for (int j = 0; j < 1; j++) { ////fdd dl number of available freq_Bands = 1
|
||||
nrfreqbanditemdl = (XNAP_NRFrequencyBandItem_t *)calloc(1, sizeof(XNAP_NRFrequencyBandItem_t));
|
||||
nrfreqbanditemdl->nr_frequency_band = fdd->dl_freqinfo.band;
|
||||
asn1cSeqAdd(&servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRFrequencyInfo.frequencyBand_List.list,
|
||||
nrfreqbanditemdl);
|
||||
}
|
||||
|
||||
switch (fdd->ul_tbw.scs) {
|
||||
case 15:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs15;
|
||||
break;
|
||||
|
||||
case 30:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs30;
|
||||
break;
|
||||
|
||||
case 60:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs60;
|
||||
break;
|
||||
|
||||
case 120:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs120;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (fdd->ul_tbw.nrb) {
|
||||
case 11:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb11;
|
||||
break;
|
||||
|
||||
case 18:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb18;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb24;
|
||||
break;
|
||||
|
||||
case 78:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb78;
|
||||
break;
|
||||
|
||||
case 106:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb106;
|
||||
break;
|
||||
|
||||
case 162:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb162;
|
||||
break;
|
||||
case 217:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb217;
|
||||
break;
|
||||
case 273:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb273;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(0, "Failed: Check value for N_RB_DL/N_RB_UL");
|
||||
break;
|
||||
}
|
||||
switch (fdd->dl_tbw.scs) {
|
||||
case 15:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs15;
|
||||
break;
|
||||
|
||||
case 30:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs30;
|
||||
break;
|
||||
|
||||
case 60:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs60;
|
||||
break;
|
||||
|
||||
case 120:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs120;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (fdd->dl_tbw.nrb) {
|
||||
case 11:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb11;
|
||||
break;
|
||||
|
||||
case 18:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb18;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb24;
|
||||
break;
|
||||
|
||||
case 78:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb78;
|
||||
break;
|
||||
|
||||
case 106:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb106;
|
||||
break;
|
||||
|
||||
case 162:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb162;
|
||||
break;
|
||||
case 217:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb217;
|
||||
break;
|
||||
case 273:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb273;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(0, "Failed: Check value for N_RB_DL/N_RB_UL");
|
||||
break;
|
||||
}
|
||||
} else if (req->info.mode == XNAP_MODE_TDD) { // TDD
|
||||
const xnap_tdd_info_t *tdd = &req->info.tdd;
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.present = XNAP_NRModeInfo_PR_tdd;
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd =
|
||||
(XNAP_NRModeInfoTDD_t *)calloc(1, sizeof(XNAP_NRModeInfoTDD_t));
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrFrequencyInfo.nrARFCN = tdd->freqinfo.arfcn;
|
||||
for (int j = 0; j < 1; j++) { // number of available bands = j = 1
|
||||
nrfreqbanditem = (XNAP_NRFrequencyBandItem_t *)calloc(1, sizeof(XNAP_NRFrequencyBandItem_t));
|
||||
nrfreqbanditem->nr_frequency_band = tdd->freqinfo.band;
|
||||
asn1cSeqAdd(&servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrFrequencyInfo.frequencyBand_List.list,
|
||||
nrfreqbanditem);
|
||||
}
|
||||
switch (tdd->tbw.scs) {
|
||||
case 15:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs15;
|
||||
break;
|
||||
|
||||
case 30:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs30;
|
||||
break;
|
||||
|
||||
case 60:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs60;
|
||||
break;
|
||||
|
||||
case 120:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs120;
|
||||
break;
|
||||
}
|
||||
switch (tdd->tbw.nrb) {
|
||||
case 11:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb11;
|
||||
break;
|
||||
|
||||
case 18:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb18;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb24;
|
||||
break;
|
||||
|
||||
case 78:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb78;
|
||||
break;
|
||||
|
||||
case 106:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb106;
|
||||
break;
|
||||
|
||||
case 162:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb162;
|
||||
break;
|
||||
case 217:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb217;
|
||||
break;
|
||||
case 273:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb273;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(0, "Failed: Check value for N_RB_DL/N_RB_UL");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Setting MTC to 0 now. Will be handled later.
|
||||
INT8_TO_OCTET_STRING(0, &servedCellMember->served_cell_info_NR.measurementTimingConfiguration);
|
||||
servedCellMember->served_cell_info_NR.connectivitySupport.eNDC_Support = 1;
|
||||
}
|
||||
asn1cSeqAdd(&ie->value.choice.ServedCells_NR.list, servedCellMember);
|
||||
}
|
||||
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
||||
|
||||
/* mandatory */ // AMFRegion
|
||||
ie = (XNAP_XnSetupRequest_IEs_t *)calloc(1, sizeof(XNAP_XnSetupRequest_IEs_t));
|
||||
ie->id = XNAP_ProtocolIE_ID_id_AMF_Region_Information;
|
||||
ie->criticality = XNAP_Criticality_reject;
|
||||
ie->value.present = XNAP_XnSetupRequest_IEs__value_PR_AMF_Region_Information;
|
||||
// for (int i=0;i<1;i++)
|
||||
{
|
||||
e_GlobalAMF_Region_Information_ItemIEs =
|
||||
(XNAP_GlobalAMF_Region_Information_t *)calloc(1, sizeof(XNAP_GlobalAMF_Region_Information_t));
|
||||
|
||||
MCC_MNC_TO_PLMNID(req->info.plmn.mcc,
|
||||
req->info.plmn.mnc,
|
||||
req->info.plmn.mnc_digit_length,
|
||||
&e_GlobalAMF_Region_Information_ItemIEs->plmn_ID);
|
||||
e_GlobalAMF_Region_Information_ItemIEs->amf_region_id.size = 1;
|
||||
e_GlobalAMF_Region_Information_ItemIEs->amf_region_id.buf =
|
||||
calloc(1, e_GlobalAMF_Region_Information_ItemIEs->amf_region_id.size);
|
||||
e_GlobalAMF_Region_Information_ItemIEs->amf_region_id.buf[0] = 80; // TODO: Hardcoded for now
|
||||
e_GlobalAMF_Region_Information_ItemIEs->amf_region_id.bits_unused = 0;
|
||||
|
||||
asn1cSeqAdd(&ie->value.choice.AMF_Region_Information.list, e_GlobalAMF_Region_Information_ItemIEs);
|
||||
}
|
||||
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
||||
|
||||
if (xnap_gNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
LOG_E(XNAP, "Failed to encode Xn setup request\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
xnap_gNB_itti_send_sctp_data_req(assoc_id, buffer, len, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xnap_gNB_generate_xn_setup_failure(sctp_assoc_t assoc_id, xnap_setup_failure_t *fail)
|
||||
{
|
||||
XNAP_XnAP_PDU_t pdu;
|
||||
XNAP_XnSetupFailure_t *out;
|
||||
XNAP_XnSetupFailure_IEs_t *ie;
|
||||
|
||||
uint8_t *buffer;
|
||||
uint32_t len;
|
||||
int ret = 0;
|
||||
|
||||
/* Prepare the XnAP message to encode */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = XNAP_XnAP_PDU_PR_unsuccessfulOutcome;
|
||||
pdu.choice.unsuccessfulOutcome = (XNAP_UnsuccessfulOutcome_t *)calloc(1, sizeof(XNAP_UnsuccessfulOutcome_t));
|
||||
pdu.choice.unsuccessfulOutcome->procedureCode = XNAP_ProcedureCode_id_xnSetup;
|
||||
pdu.choice.unsuccessfulOutcome->criticality = XNAP_Criticality_reject;
|
||||
pdu.choice.unsuccessfulOutcome->value.present = XNAP_UnsuccessfulOutcome__value_PR_XnSetupFailure;
|
||||
out = &pdu.choice.unsuccessfulOutcome->value.choice.XnSetupFailure;
|
||||
|
||||
/* mandatory */
|
||||
ie = (XNAP_XnSetupFailure_IEs_t *)calloc(1, sizeof(XNAP_XnSetupFailure_IEs_t));
|
||||
ie->id = XNAP_ProtocolIE_ID_id_Cause;
|
||||
ie->criticality = XNAP_Criticality_ignore;
|
||||
ie->value.present = XNAP_XnSetupFailure_IEs__value_PR_Cause;
|
||||
|
||||
xnap_gNB_set_cause(&ie->value.choice.Cause, fail->cause_type, fail->cause_value);
|
||||
|
||||
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
||||
|
||||
if (xnap_gNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
LOG_E(XNAP, "Failed to encode Xn setup failure\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
xnap_gNB_itti_send_sctp_data_req(assoc_id, buffer, len, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xnap_gNB_set_cause(XNAP_Cause_t *cause_p, XNAP_Cause_PR cause_type, long cause_value)
|
||||
{
|
||||
DevAssert(cause_p != NULL);
|
||||
|
||||
switch (cause_type) {
|
||||
case XNAP_CAUSE_RADIO_NETWORK:
|
||||
cause_p->present = XNAP_Cause_PR_radioNetwork;
|
||||
cause_p->choice.radioNetwork = cause_value;
|
||||
break;
|
||||
|
||||
case XNAP_CAUSE_TRANSPORT:
|
||||
cause_p->present = XNAP_Cause_PR_transport;
|
||||
cause_p->choice.transport = cause_value;
|
||||
break;
|
||||
|
||||
case XNAP_CAUSE_PROTOCOL:
|
||||
cause_p->present = XNAP_Cause_PR_protocol;
|
||||
cause_p->choice.protocol = cause_value;
|
||||
break;
|
||||
|
||||
case XNAP_CAUSE_MISC:
|
||||
cause_p->present = XNAP_Cause_PR_misc;
|
||||
cause_p->choice.misc = cause_value;
|
||||
break;
|
||||
|
||||
case XNAP_CAUSE_NOTHING:
|
||||
default:
|
||||
cause_p->present = XNAP_Cause_PR_NOTHING;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xnap_gNB_generate_xn_setup_response(sctp_assoc_t assoc_id, xnap_setup_resp_t *resp)
|
||||
// xnap_gNB_instance_t *instance_p, xnap_gNB_data_t *xnap_gNB_data_p)
|
||||
{
|
||||
XNAP_XnAP_PDU_t pdu;
|
||||
uint8_t *buffer = NULL;
|
||||
uint32_t len = 0;
|
||||
int ret = 0;
|
||||
XNAP_XnSetupResponse_t *out;
|
||||
XNAP_XnSetupResponse_IEs_t *ie;
|
||||
XNAP_PLMN_Identity_t *plmn;
|
||||
XNAP_BroadcastPLMNinTAISupport_Item_t *e_BroadcastPLMNinTAISupport_ItemIE;
|
||||
XNAP_TAISupport_Item_t *TAISupport_ItemIEs;
|
||||
XNAP_S_NSSAI_t *e_S_NSSAI_ItemIE;
|
||||
// XNAP_GlobalAMF_Region_Information_t *e_GlobalAMF_Region_Information_ItemIEs;
|
||||
XNAP_ServedCells_NR_Item_t *servedCellMember;
|
||||
// XNAP_ServedCells_NR_t *ServedCells_NR;
|
||||
XNAP_NRFrequencyBandItem_t *nrfreqbanditemul;
|
||||
XNAP_NRFrequencyBandItem_t *nrfreqbanditemdl;
|
||||
XNAP_NRFrequencyBandItem_t *nrfreqbanditem;
|
||||
|
||||
/* Prepare the XNAP message to encode */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = XNAP_XnAP_PDU_PR_successfulOutcome;
|
||||
pdu.choice.successfulOutcome = (XNAP_SuccessfulOutcome_t *)calloc(1, sizeof(XNAP_SuccessfulOutcome_t));
|
||||
pdu.choice.successfulOutcome->procedureCode = XNAP_ProcedureCode_id_xnSetup;
|
||||
pdu.choice.successfulOutcome->criticality = XNAP_Criticality_reject;
|
||||
pdu.choice.successfulOutcome->value.present = XNAP_SuccessfulOutcome__value_PR_XnSetupResponse;
|
||||
out = &pdu.choice.successfulOutcome->value.choice.XnSetupResponse;
|
||||
|
||||
/* mandatory */
|
||||
ie = (XNAP_XnSetupResponse_IEs_t *)calloc(1, sizeof(XNAP_XnSetupResponse_IEs_t));
|
||||
ie->id = XNAP_ProtocolIE_ID_id_GlobalNG_RAN_node_ID;
|
||||
ie->criticality = XNAP_Criticality_reject;
|
||||
ie->value.present = XNAP_XnSetupResponse_IEs__value_PR_GlobalNG_RANNode_ID;
|
||||
ie->value.choice.GlobalNG_RANNode_ID.present = XNAP_GlobalNG_RANNode_ID_PR_gNB;
|
||||
ie->value.choice.GlobalNG_RANNode_ID.choice.gNB = (XNAP_GlobalgNB_ID_t *)calloc(1, sizeof(XNAP_GlobalgNB_ID_t));
|
||||
MCC_MNC_TO_PLMNID(resp->info.plmn.mcc,
|
||||
resp->info.plmn.mnc,
|
||||
resp->info.plmn.mnc_digit_length,
|
||||
&ie->value.choice.GlobalNG_RANNode_ID.choice.gNB->plmn_id);
|
||||
ie->value.choice.GlobalNG_RANNode_ID.choice.gNB->gnb_id.present = XNAP_GNB_ID_Choice_PR_gnb_ID;
|
||||
MACRO_GNB_ID_TO_BIT_STRING(resp->gNB_id, &ie->value.choice.GlobalNG_RANNode_ID.choice.gNB->gnb_id.choice.gnb_ID);
|
||||
LOG_I(XNAP,
|
||||
"%ld -> %02x%02x%02x\n",
|
||||
resp->gNB_id,
|
||||
ie->value.choice.GlobalNG_RANNode_ID.choice.gNB->gnb_id.choice.gnb_ID.buf[0],
|
||||
ie->value.choice.GlobalNG_RANNode_ID.choice.gNB->gnb_id.choice.gnb_ID.buf[1],
|
||||
ie->value.choice.GlobalNG_RANNode_ID.choice.gNB->gnb_id.choice.gnb_ID.buf[2]);
|
||||
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
||||
|
||||
/* mandatory */ // TAI Support list
|
||||
ie = (XNAP_XnSetupResponse_IEs_t *)calloc(1, sizeof(XNAP_XnSetupResponse_IEs_t));
|
||||
ie->id = XNAP_ProtocolIE_ID_id_TAISupport_list;
|
||||
ie->criticality = XNAP_Criticality_reject;
|
||||
ie->value.present = XNAP_XnSetupResponse_IEs__value_PR_TAISupport_List;
|
||||
|
||||
for (int i = 0; i < 1; i++) {
|
||||
TAISupport_ItemIEs = (XNAP_TAISupport_Item_t *)calloc(1, sizeof(XNAP_TAISupport_Item_t));
|
||||
INT24_TO_OCTET_STRING(resp->tai_support, &TAISupport_ItemIEs->tac);
|
||||
{
|
||||
for (int j = 0; j < 1; j++) {
|
||||
e_BroadcastPLMNinTAISupport_ItemIE =
|
||||
(XNAP_BroadcastPLMNinTAISupport_Item_t *)calloc(1, sizeof(XNAP_BroadcastPLMNinTAISupport_Item_t));
|
||||
|
||||
MCC_MNC_TO_PLMNID(resp->info.plmn.mcc,
|
||||
resp->info.plmn.mnc,
|
||||
resp->info.plmn.mnc_digit_length,
|
||||
&e_BroadcastPLMNinTAISupport_ItemIE->plmn_id);
|
||||
|
||||
{
|
||||
for (int k = 0; k < 1; k++) {
|
||||
e_S_NSSAI_ItemIE = (XNAP_S_NSSAI_t *)calloc(1, sizeof(XNAP_S_NSSAI_t));
|
||||
e_S_NSSAI_ItemIE->sst.size = 1; // OCTET STRING(SIZE(1))
|
||||
e_S_NSSAI_ItemIE->sst.buf = calloc(e_S_NSSAI_ItemIE->sst.size, sizeof(OCTET_STRING_t));
|
||||
e_S_NSSAI_ItemIE->sst.buf[0] = 1;
|
||||
|
||||
asn1cSeqAdd(&e_BroadcastPLMNinTAISupport_ItemIE->tAISliceSupport_List.list, e_S_NSSAI_ItemIE);
|
||||
}
|
||||
}
|
||||
asn1cSeqAdd(&TAISupport_ItemIEs->broadcastPLMNs.list, e_BroadcastPLMNinTAISupport_ItemIE);
|
||||
}
|
||||
}
|
||||
asn1cSeqAdd(&ie->value.choice.TAISupport_List.list, TAISupport_ItemIEs);
|
||||
}
|
||||
//}
|
||||
|
||||
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
||||
|
||||
/* mandatory */
|
||||
ie = (XNAP_XnSetupResponse_IEs_t *)calloc(1, sizeof(XNAP_XnSetupResponse_IEs_t));
|
||||
ie->id = XNAP_ProtocolIE_ID_id_List_of_served_cells_NR;
|
||||
ie->criticality = XNAP_Criticality_reject;
|
||||
ie->value.present = XNAP_XnSetupResponse_IEs__value_PR_ServedCells_NR;
|
||||
{
|
||||
servedCellMember = (XNAP_ServedCells_NR_Item_t *)calloc(1, sizeof(XNAP_ServedCells_NR_Item_t));
|
||||
servedCellMember->served_cell_info_NR.nrPCI = resp->info.nr_pci; // long
|
||||
|
||||
MCC_MNC_TO_PLMNID(resp->info.plmn.mcc,
|
||||
resp->info.plmn.mnc,
|
||||
resp->info.plmn.mnc_digit_length,
|
||||
&servedCellMember->served_cell_info_NR.cellID.plmn_id); // octet string
|
||||
NR_CELL_ID_TO_BIT_STRING(resp->gNB_id,
|
||||
&servedCellMember->served_cell_info_NR.cellID.nr_CI); // bit string
|
||||
|
||||
INT24_TO_OCTET_STRING(resp->tai_support, &servedCellMember->served_cell_info_NR.tac); // octet string
|
||||
for (int k = 0; k < 1; k++) {
|
||||
plmn = (XNAP_PLMN_Identity_t *)calloc(1, sizeof(XNAP_PLMN_Identity_t));
|
||||
{
|
||||
MCC_MNC_TO_PLMNID(resp->info.plmn.mcc, resp->info.plmn.mnc, resp->info.plmn.mnc_digit_length, plmn);
|
||||
asn1cSeqAdd(&servedCellMember->served_cell_info_NR.broadcastPLMN.list, plmn);
|
||||
}
|
||||
}
|
||||
|
||||
if (resp->info.mode == XNAP_MODE_FDD) { // FDD
|
||||
const xnap_fdd_info_t *fdd = &resp->info.fdd;
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.present = XNAP_NRModeInfo_PR_fdd;
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd = (XNAP_NRModeInfoFDD_t *)calloc(1, sizeof(XNAP_NRModeInfoFDD_t));
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRFrequencyInfo.nrARFCN = fdd->ul_freqinfo.arfcn;
|
||||
for (int j = 0; j < 1; j++) { // fdd ul number of available freq_Bands = 1
|
||||
nrfreqbanditemul = (XNAP_NRFrequencyBandItem_t *)calloc(1, sizeof(XNAP_NRFrequencyBandItem_t));
|
||||
nrfreqbanditemul->nr_frequency_band = fdd->ul_freqinfo.band;
|
||||
asn1cSeqAdd(&servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRFrequencyInfo.frequencyBand_List.list,
|
||||
nrfreqbanditemul);
|
||||
}
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRFrequencyInfo.nrARFCN = fdd->dl_freqinfo.arfcn;
|
||||
for (int j = 0; j < 1; j++) { ////fdd dl number of available freq_Bands = 1
|
||||
nrfreqbanditemdl = (XNAP_NRFrequencyBandItem_t *)calloc(1, sizeof(XNAP_NRFrequencyBandItem_t));
|
||||
nrfreqbanditemdl->nr_frequency_band = fdd->dl_freqinfo.band;
|
||||
asn1cSeqAdd(&servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRFrequencyInfo.frequencyBand_List.list,
|
||||
nrfreqbanditemdl);
|
||||
}
|
||||
switch (fdd->ul_tbw.scs) {
|
||||
case 15:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs15;
|
||||
break;
|
||||
case 30:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs30;
|
||||
break;
|
||||
case 60:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs60;
|
||||
break;
|
||||
case 120:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs120;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (fdd->ul_tbw.nrb) {
|
||||
case 0:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb11;
|
||||
break;
|
||||
case 1:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb18;
|
||||
break;
|
||||
case 2:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb24;
|
||||
break;
|
||||
case 11:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb78;
|
||||
break;
|
||||
case 14:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb106;
|
||||
break;
|
||||
case 21:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb162;
|
||||
break;
|
||||
case 24:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb217;
|
||||
break;
|
||||
case 28:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->ulNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb273;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(0, "Failed: Check value for N_RB_DL/N_RB_UL");
|
||||
break;
|
||||
}
|
||||
switch (fdd->dl_tbw.scs) {
|
||||
case 15:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs15;
|
||||
break;
|
||||
case 30:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs30;
|
||||
break;
|
||||
case 60:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs60;
|
||||
break;
|
||||
case 120:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs120;
|
||||
break;
|
||||
}
|
||||
switch (fdd->dl_tbw.nrb) {
|
||||
case 0:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb11;
|
||||
break;
|
||||
case 1:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb18;
|
||||
break;
|
||||
case 2:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb24;
|
||||
break;
|
||||
case 11:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb78;
|
||||
break;
|
||||
case 14:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb106;
|
||||
break;
|
||||
case 21:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb162;
|
||||
break;
|
||||
case 24:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb217;
|
||||
break;
|
||||
case 28:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.fdd->dlNRTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb273;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(0, "Failed: Check value for N_RB_DL/N_RB_UL"); // TODO: Add all values or function to convert
|
||||
break;
|
||||
}
|
||||
} else if (resp->info.mode == XNAP_MODE_TDD) { // TDD
|
||||
const xnap_tdd_info_t *tdd = &resp->info.tdd;
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.present = XNAP_NRModeInfo_PR_tdd;
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd = (XNAP_NRModeInfoTDD_t *)calloc(1, sizeof(XNAP_NRModeInfoTDD_t));
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrFrequencyInfo.nrARFCN = tdd->freqinfo.arfcn;
|
||||
for (int j = 0; j < 1; j++) { // number of available bands = j = 1
|
||||
nrfreqbanditem = (XNAP_NRFrequencyBandItem_t *)calloc(1, sizeof(XNAP_NRFrequencyBandItem_t));
|
||||
nrfreqbanditem->nr_frequency_band = tdd->freqinfo.band;
|
||||
asn1cSeqAdd(&servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrFrequencyInfo.frequencyBand_List.list,
|
||||
nrfreqbanditem);
|
||||
}
|
||||
switch (tdd->tbw.scs) {
|
||||
case 15:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs15;
|
||||
break;
|
||||
case 30:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs30;
|
||||
break;
|
||||
case 60:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs60;
|
||||
break;
|
||||
case 120:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRSCS = XNAP_NRSCS_scs120;
|
||||
break;
|
||||
}
|
||||
switch (tdd->tbw.nrb) {
|
||||
case 0:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb11;
|
||||
break;
|
||||
case 1:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb18;
|
||||
break;
|
||||
case 2:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb24;
|
||||
break;
|
||||
case 11:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb78;
|
||||
break;
|
||||
case 14:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb106;
|
||||
break;
|
||||
case 21:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb162;
|
||||
break;
|
||||
case 24:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb217;
|
||||
break;
|
||||
case 28:
|
||||
servedCellMember->served_cell_info_NR.nrModeInfo.choice.tdd->nrTransmissonBandwidth.nRNRB = XNAP_NRNRB_nrb273;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(0, "Failed: Check value for N_RB_DL/N_RB_UL"); // TODO: Add all values or function to convert.
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Setting MTC to 0 now. Will be handled later.
|
||||
INT8_TO_OCTET_STRING(0, &servedCellMember->served_cell_info_NR.measurementTimingConfiguration);
|
||||
servedCellMember->served_cell_info_NR.connectivitySupport.eNDC_Support = 1;
|
||||
asn1cSeqAdd(&ie->value.choice.ServedCells_NR.list, servedCellMember);
|
||||
}
|
||||
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
||||
|
||||
if (xnap_gNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
LOG_E(XNAP, "Failed to encode Xn setup response\n");
|
||||
return -1;
|
||||
}
|
||||
xnap_gNB_itti_send_sctp_data_req(assoc_id, buffer, len, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//int xnap_gNB_generate_xn_handover_request (sctp_assoc_t assoc_id, instance_t instance,
|
||||
// xnap_handover_req_t *xnap_handover_req, int ue_id)
|
||||
int xnap_gNB_generate_xn_handover_request (sctp_assoc_t assoc_id, xnap_handover_req_t *xnap_handover_req)
|
||||
{
|
||||
|
||||
XNAP_XnAP_PDU_t pdu;
|
||||
XNAP_HandoverRequest_t *xnhandoverreq;
|
||||
XNAP_HandoverRequest_IEs_t *ie;
|
||||
// instance_t instance;
|
||||
|
||||
uint8_t *buffer;
|
||||
uint32_t len;
|
||||
int ret = 0;
|
||||
//get intance from tree if needed
|
||||
// DevAssert(instance != NULL); //not pointer
|
||||
// DevAssert(xnap_gNB_data_p != NULL);// not defined
|
||||
|
||||
// DevAssert(pdu != NULL);
|
||||
xnhandoverreq = &pdu.choice.initiatingMessage->value.choice.HandoverRequest;
|
||||
/* Send a xn setup failure with protocol cause unspecified */
|
||||
/* MessageDef *message_p = itti_alloc_new_message(TASK_XNAP, 0, XNAP_FAILURE_REQ);// failure????
|
||||
message_p->ittiMsgHeader.originInstance = assoc_id;
|
||||
itti_send_msg_to_task(TASK_XNAP, 0, message_p); */
|
||||
|
||||
LOG_D(XNAP, "Received a new XN setup request\n");
|
||||
|
||||
/* Prepare the XnAP handover message to encode */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = XNAP_XnAP_PDU_PR_initiatingMessage;
|
||||
pdu.choice.initiatingMessage->procedureCode = XNAP_ProcedureCode_id_handoverPreparation;
|
||||
pdu.choice.initiatingMessage->criticality = XNAP_Criticality_reject;
|
||||
pdu.choice.initiatingMessage->value.present = XNAP_InitiatingMessage__value_PR_HandoverRequest;
|
||||
xnhandoverreq = &pdu.choice.initiatingMessage->value.choice.HandoverRequest;
|
||||
|
||||
/* mandatory */
|
||||
ie = (XNAP_HandoverRequest_IEs_t *)calloc(1, sizeof(XNAP_HandoverRequest_IEs_t));
|
||||
ie->id = XNAP_ProtocolIE_ID_id_sourceNG_RANnodeUEXnAPID;
|
||||
ie->criticality = XNAP_Criticality_reject;
|
||||
ie->value.present = XNAP_HandoverRequest_IEs__value_PR_NG_RANnodeUEXnAPID;
|
||||
// ie->value.choice.UE_XnAP_ID = xnap_id_get_id_source(&instance_p->id_manager, ue_id);//// value to be added.
|
||||
asn1cSeqAdd(&xnhandoverreq->protocolIEs.list, ie);
|
||||
|
||||
/* mandatory */
|
||||
ie = (XNAP_HandoverRequest_IEs_t *)calloc(1, sizeof(XNAP_HandoverRequest_IEs_t));
|
||||
ie->id = XNAP_ProtocolIE_ID_id_Cause;
|
||||
ie->criticality = XNAP_Criticality_ignore;
|
||||
ie->value.present = XNAP_HandoverRequest_IEs__value_PR_Cause;
|
||||
ie->value.choice.Cause.present = XNAP_Cause_PR_radioNetwork;
|
||||
ie->value.choice.Cause.choice.radioNetwork = 1; //Xnap_CauseRadioNetwork_handover_desirable_for_radio_reasons;
|
||||
asn1cSeqAdd(&xnhandoverreq->protocolIEs.list, ie);
|
||||
|
||||
/* mandatory */
|
||||
ie = (XNAP_HandoverRequest_IEs_t *)calloc(1, sizeof(XNAP_HandoverRequest_IEs_t));
|
||||
ie->id = XNAP_ProtocolIE_ID_id_TargetCellCGI;
|
||||
ie->criticality = XNAP_Criticality_reject;
|
||||
ie->value.present = XNAP_HandoverRequest_IEs__value_PR_Target_CGI;
|
||||
ie->value.choice.Target_CGI.present = XNAP_Target_CGI_PR_nr;
|
||||
ie->value.choice.Target_CGI.choice.nr = (XNAP_NR_CGI_t *)calloc(1, sizeof(XNAP_NR_CGI_t));
|
||||
MCC_MNC_TO_PLMNID(xnap_handover_req->plmn_id.mcc,/// correct
|
||||
xnap_handover_req->plmn_id.mnc,
|
||||
xnap_handover_req->plmn_id.mnc_digit_length,
|
||||
&ie->value.choice.Target_CGI.choice.nr->plmn_id);
|
||||
NR_CELL_ID_TO_BIT_STRING(xnap_handover_req->target_cgi.cgi,
|
||||
&ie->value.choice.Target_CGI.choice.nr->nr_CI); // bit string
|
||||
asn1cSeqAdd(&xnhandoverreq->protocolIEs.list, ie);
|
||||
|
||||
/* mandatory */
|
||||
/** ie = (XNAP_HandoverRequest_IEs_t *)calloc(1, sizeof(XNAP_HandoverRequest_IEs_t));
|
||||
ie->id = Xnap_ProtocolIE_ID_id_GUAMI;
|
||||
ie->criticality = XNAP_Criticality_reject;
|
||||
ie->value.present = Xnap_HandoverRequest_IEs__value_PR_GUAMI;
|
||||
ie->value.choice.GUAMI.present = XNAP_Cause_PR_GUAMI;
|
||||
//ie->value.choice.GUAMI = (XNAP_GUAMI_t *)calloc(1, sizeof(XNAP_GUAMI_t));// what is the need? guami not pointer i think
|
||||
MCC_MNC_TO_PLMNID(req->info.plmn.mcc,
|
||||
req->info.plmn.mnc,
|
||||
req->info.plmn.mnc_digit_length,
|
||||
&ie->value.choice.GUAMI.choice.plmn_ID);////handover req structure
|
||||
ie->value.choice.GUAMI.choice.amf_region_id = 1;//TODO: hardcoded
|
||||
ie->value.choice.GUAMI.choice.amf_set_id = 1;
|
||||
ie->value.choice.GUAMI.choice.amf_pointer = 1;
|
||||
asn1cSeqAdd(&out->protocolIEs.list, ie); **/
|
||||
|
||||
/* mandatory */
|
||||
/** ie = (XNAP_HandoverRequest_IEs_t *)calloc(1, sizeof(XNAP_HandoverRequest_IEs_t));
|
||||
ie->id = Xnap_ProtocolIE_ID_id_UE_ContextInformation;
|
||||
ie->criticality = XNAP_Criticality_reject;
|
||||
ie->value.present = Xnap_ProtocolIE_ID_id_UEContextInfoHORequest;
|
||||
//@TODO: consider to update this value
|
||||
ie->value.choice.UEContextInfoHORequest.ng_c_UE_reference = xnap_handover_req->ngc_ue_sig_ref; //what about other mandatory things in this IE? **/
|
||||
|
||||
/* mandatory */
|
||||
/*ie = (Xnap_CPTransportLayerInformation_t *)calloc(4, sizeof(XNAP_HandoverRequest_IEs_t));
|
||||
cptlinfo->present = Xnap_CPTransportLayerInformation_PR_endpointIPAddress;
|
||||
cptlinfo->choice.endpointIPAddress.size = 4 ; //endian ness has to be verified here
|
||||
cptlinfo->value.choice.cp_TNL_info_source = xnap_handover_req->cp_TNL_info_source;*/ /// where is this storing now??
|
||||
|
||||
// KGNB_STAR_TO_BIT_STRING(xnap_handover_req->kgnb,&ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_gNB_star); //function not there
|
||||
|
||||
/** if (xnap_handover_req->kgnb_ncc >=0) { // Check this condition
|
||||
ie->value.choice.UEContextInfoHORequest.aS_SecurityInformation.nextHopChainingCount = xnap_handover_req->ue_context.as_security_ncc;
|
||||
}
|
||||
else {
|
||||
ie->value.choice.UEContextInfoHORequest.aS_SecurityInformation.nextHopChainingCount = 1;
|
||||
} **/
|
||||
|
||||
/* id-NRUESecurityCapabilities */
|
||||
/*XNAP_FIND_PROTOCOLIE_BY_ID(Xnap_HandoverRequest_IEs_t, ie, container,
|
||||
XNAP_ProtocolIE_ID_id_NRUESecurityCapabilities, false);
|
||||
if (ie != NULL) {
|
||||
xnap_handover_req.nr_security_capabilities.encryption_algorithms =
|
||||
BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRencryptionAlgorithms);
|
||||
xnap_handover_req.nr_security_capabilities.integrity_algorithms =
|
||||
BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRintegrityProtectionAlgorithms);
|
||||
} else {
|
||||
xnap_handover_req.nr_security_capabilities.encryption_algorithms = 0;
|
||||
xnap_handover_req.nr_security_capabilities.integrity_algorithms = 0;
|
||||
}*/ //// why this is here???? not filling ie
|
||||
|
||||
|
||||
OCTET_STRING_fromBuf(&ie->value.choice.UEContextInfoHORequest.rrc_Context, (char*) xnap_handover_req->ue_context.rrc_buffer, 8192);// added 8192- need to remove hard coding
|
||||
|
||||
asn1cSeqAdd(&xnhandoverreq->protocolIEs.list, ie);
|
||||
|
||||
/* mandatory */
|
||||
/** ie = (XNAP_HandoverRequest_IEs_t *)calloc(1, sizeof(XNAP_HandoverRequest_IEs_t));
|
||||
ie->id = Xnap_ProtocolIE_ID_id_UE_HistoryInformation;
|
||||
ie->criticality = XNAP_Criticality_ignore;
|
||||
ie->value.present = Xnap_HandoverRequest_IEs__value_PR_UE_HistoryInformation;
|
||||
//@TODO: consider to update this value
|
||||
{
|
||||
lastVisitedCell_Item = (XNAP_LastVisitedCell_Item *)calloc(1, sizeof(XNAP_LastVisitedCell_Item));
|
||||
lastVisitedCell_Item->present = XNAP_LastVisitedCell_Item_PR_nG_RAN_Cell; **/
|
||||
/* MCC_MNC_TO_PLMNID(xnap_handover_req->plmn_id.mcc, xnap_handover_req->plmn_id.mnc, xnap_handover_req->plmn_id.mnc_digit_length,
|
||||
&lastVisitedCell_Item->choice.nG_RAN_Cell.global_Cell_ID.pLMN_Identity);
|
||||
MACRO_ENB_ID_TO_CELL_IDENTITY(0, 0, &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.ng_RANcellIdentifier);
|
||||
lastVisitedCell_Item->choice.ngRAN_Cell.cellType.cell_Size = XNAP_Cell_Size_small;
|
||||
lastVisitedCell_Item->choice.ngRAN_Cell.time_UE_StayedInCell = 2;
|
||||
asn1cSeqAdd(&ie->value.choice.UE_HistoryInformation.list, lastVisitedCell_Item);*/ ///its octet string ryt??
|
||||
/** } **/
|
||||
|
||||
// asn1cSeqAdd(&out->protocolIEs.list, ie);
|
||||
|
||||
if (xnap_gNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
LOG_E(XNAP,"Failed to encode XN handover request\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
xnap_gNB_itti_send_sctp_data_req(assoc_id, buffer, len, 0); /////where do you get the assoc id from??
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** getting assoc-id- sharing this clip from F1AP
|
||||
* int f1ap_assoc_id(F1_t isCu, instance_t instanceP) {
|
||||
f1ap_setup_req_t *f1_inst=f1ap_req(isCu, instanceP);
|
||||
return f1_inst->assoc_id;
|
||||
}
|
||||
If method that we have implemented to fetch assoc_id is not correct, need to try this
|
||||
|
||||
**/
|
||||
|
||||
/**
|
||||
void rrc_gNB_process_HandoverPreparationInformation(//// why is this here? should be in RRC
|
||||
rrc_gNB_ue_context_t ue_context_p,
|
||||
uint8_t *buffer,
|
||||
int *size)
|
||||
{
|
||||
memset(buffer, 0, 8192);
|
||||
char *ho_buf = (char *) buffer;
|
||||
int ho_size;
|
||||
ho_size = do_NRHandoverPreparation(ho_buf, 8192, ue_context_p.ue_context.UE_Capability_nr, ue_context_p.ue_context.UE_Capability_size);
|
||||
*size = ho_size;
|
||||
|
||||
|
||||
} **/
|
||||
44
openair2/XNAP/xnap_gNB_generate_messages.h
Normal file
44
openair2/XNAP/xnap_gNB_generate_messages.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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 xnap_gNB_generate_messages.h
|
||||
* \brief xnap procedures for gNB
|
||||
* \date 2023 July
|
||||
* \version 1.0
|
||||
*/
|
||||
|
||||
#ifndef XNAP_GNB_GENERATE_MESSAGES_H_
|
||||
#define XNAP_GNB_GENERATE_MESSAGES_H_
|
||||
|
||||
#include "xnap_gNB_defs.h"
|
||||
#include "xnap_common.h"
|
||||
|
||||
int xnap_gNB_generate_xn_setup_request(sctp_assoc_t assoc_id, xnap_setup_req_t *req);
|
||||
|
||||
int xnap_gNB_generate_xn_setup_response(sctp_assoc_t assoc_id, xnap_setup_resp_t *resp);
|
||||
|
||||
int xnap_gNB_generate_xn_setup_failure(sctp_assoc_t assoc_id, xnap_setup_failure_t *fail);
|
||||
|
||||
int xnap_gNB_set_cause(XNAP_Cause_t *cause_p, XNAP_Cause_PR cause_type, long cause_value);
|
||||
|
||||
//int xnap_gNB_generate_xn_handover_request(instance_t instance, xnap_handover_req_t *xnap_handover_req, int ue_id);
|
||||
int xnap_gNB_generate_xn_handover_request(sctp_assoc_t assoc_id, xnap_handover_req_t *xnap_handover_req);
|
||||
#endif /* XNAP_GNB_GENERATE_MESSAGES_H_ */
|
||||
360
openair2/XNAP/xnap_gNB_handler.c
Normal file
360
openair2/XNAP/xnap_gNB_handler.c
Normal file
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
* 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 xnap_gNB_handler.c
|
||||
* \brief xnap handler procedures for gNB
|
||||
* \author Sreeshma Shiv <sreeshmau@iisc.ac.in>
|
||||
* \date August 2023
|
||||
* \version 1.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "intertask_interface.h"
|
||||
#include "xnap_common.h"
|
||||
#include "xnap_ids.h"
|
||||
#include "xnap_gNB_defs.h"
|
||||
#include "xnap_gNB_handler.h"
|
||||
#include "xnap_gNB_interface_management.h"
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
|
||||
static int xnap_gNB_handle_handover_preparation(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, XNAP_XnAP_PDU_t *pdu);
|
||||
|
||||
/* Placement of callback functions according to XNAP_ProcedureCode.h */
|
||||
static const xnap_message_decoded_callback xnap_messages_callback[][3] = {
|
||||
{xnap_gNB_handle_handover_preparation, 0, 0}, /* handoverPreparation */
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{xnap_gNB_handle_xn_setup_request, xnap_gNB_handle_xn_setup_response, xnap_gNB_handle_xn_setup_failure}, /* xnSetup */
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0}};
|
||||
|
||||
static const char *const xnap_direction_String[] = {
|
||||
"", /* Nothing */
|
||||
"Originating message", /* originating message */
|
||||
"Successfull outcome", /* successfull outcome */
|
||||
"UnSuccessfull outcome", /* successfull outcome */
|
||||
};
|
||||
const char *xnap_direction2String(int xnap_dir)
|
||||
{
|
||||
return (xnap_direction_String[xnap_dir]);
|
||||
}
|
||||
|
||||
/** Commented it for now **
|
||||
int xnap_assoc_id(F1_t isXNAP, instance_t instanceP) {
|
||||
xnap_setup_req_t *xnap_inst=xnap_req(isXNAP, instanceP);
|
||||
return xnap_inst->assoc_id;
|
||||
} **/
|
||||
|
||||
|
||||
int xnap_gNB_handle_message(instance_t instance,
|
||||
sctp_assoc_t assoc_id,
|
||||
int32_t stream,
|
||||
const uint8_t *const data,
|
||||
const uint32_t data_length)
|
||||
{
|
||||
XNAP_XnAP_PDU_t pdu;
|
||||
int ret = 0;
|
||||
|
||||
DevAssert(data != NULL);
|
||||
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
|
||||
printf("Data length received: %d\n", data_length);
|
||||
if (xnap_gNB_decode_pdu(&pdu, data, data_length) < 0) {
|
||||
LOG_E(XNAP, "Failed to decode PDU\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (pdu.present) {
|
||||
case XNAP_XnAP_PDU_PR_initiatingMessage:
|
||||
LOG_I(XNAP, "xnap_gNB_decode_initiating_message!\n");
|
||||
/* Checking procedure Code and direction of message */
|
||||
if (pdu.choice.initiatingMessage->procedureCode
|
||||
>= sizeof(xnap_messages_callback) / (3 * sizeof(xnap_message_decoded_callback))) {
|
||||
//|| (pdu.present > XNAP_XnAP_PDU_PR_unsuccessfulOutcome)) {
|
||||
LOG_E(XNAP, "[SCTP %d] Either procedureCode %ld exceed expected\n", assoc_id, pdu.choice.initiatingMessage->procedureCode);
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_XNAP_XnAP_PDU, &pdu);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* No handler present */
|
||||
if (xnap_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1] == NULL) {
|
||||
LOG_E(XNAP,
|
||||
"[SCTP %d] No handler for procedureCode %ld in %s\n",
|
||||
assoc_id,
|
||||
pdu.choice.initiatingMessage->procedureCode,
|
||||
xnap_direction2String(pdu.present - 1));
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_XNAP_XnAP_PDU, &pdu);
|
||||
return -1;
|
||||
}
|
||||
/* Calling the right handler */
|
||||
ret =
|
||||
(*xnap_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1])(instance, assoc_id, stream, &pdu);
|
||||
break;
|
||||
|
||||
case XNAP_XnAP_PDU_PR_successfulOutcome:
|
||||
LOG_I(XNAP, "xnap_gNB_decode_successfuloutcome_message!\n");
|
||||
/* Checking procedure Code and direction of message */
|
||||
if (pdu.choice.successfulOutcome->procedureCode
|
||||
>= sizeof(xnap_messages_callback) / (3 * sizeof(xnap_message_decoded_callback))) {
|
||||
LOG_E(XNAP, "[SCTP %d] Either procedureCode %ld exceed expected\n", assoc_id, pdu.choice.successfulOutcome->procedureCode);
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_XNAP_XnAP_PDU, &pdu);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* No handler present.*/
|
||||
if (xnap_messages_callback[pdu.choice.successfulOutcome->procedureCode][pdu.present - 1] == NULL) {
|
||||
LOG_E(XNAP,
|
||||
"[SCTP %d] No handler for procedureCode %ld in %s\n",
|
||||
assoc_id,
|
||||
pdu.choice.successfulOutcome->procedureCode,
|
||||
xnap_direction2String(pdu.present - 1));
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_XNAP_XnAP_PDU, &pdu);
|
||||
return -1;
|
||||
}
|
||||
/* Calling the right handler */
|
||||
ret =
|
||||
(*xnap_messages_callback[pdu.choice.successfulOutcome->procedureCode][pdu.present - 1])(instance, assoc_id, stream, &pdu);
|
||||
break;
|
||||
|
||||
case XNAP_XnAP_PDU_PR_unsuccessfulOutcome:
|
||||
LOG_I(XNAP, "xnap_gNB_decode_unsuccessfuloutcome_message!\n");
|
||||
/* Checking procedure Code and direction of message */
|
||||
if (pdu.choice.unsuccessfulOutcome->procedureCode
|
||||
>= sizeof(xnap_messages_callback) / (3 * sizeof(xnap_message_decoded_callback))) {
|
||||
LOG_E(XNAP,
|
||||
"[SCTP %d] Either procedureCode %ld exceed expected\n",
|
||||
assoc_id,
|
||||
pdu.choice.unsuccessfulOutcome->procedureCode);
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_XNAP_XnAP_PDU, &pdu);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* No handler present */
|
||||
if (xnap_messages_callback[pdu.choice.unsuccessfulOutcome->procedureCode][pdu.present - 1] == NULL) {
|
||||
LOG_E(XNAP,
|
||||
"[SCTP %d] No handler for procedureCode %ld in %s\n",
|
||||
assoc_id,
|
||||
pdu.choice.unsuccessfulOutcome->procedureCode,
|
||||
xnap_direction2String(pdu.present - 1));
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_XNAP_XnAP_PDU, &pdu);
|
||||
return -1;
|
||||
}
|
||||
/* Calling the right handler */
|
||||
ret = (*xnap_messages_callback[pdu.choice.unsuccessfulOutcome->procedureCode][pdu.present - 1])(instance,
|
||||
assoc_id,
|
||||
stream,
|
||||
&pdu);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(XNAP, "[SCTP %d] Direction %d exceed expected\n", assoc_id, pdu.present);
|
||||
break;
|
||||
}
|
||||
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_XNAP_XnAP_PDU, &pdu);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int xnap_gNB_handle_handover_preparation(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, XNAP_XnAP_PDU_t *pdu)
|
||||
{
|
||||
|
||||
XNAP_HandoverRequest_t *xnHandoverRequest;
|
||||
XNAP_HandoverRequest_IEs_t *ie;
|
||||
|
||||
// XNAP_PDUSessionResourcesToBeSetup_List_t *PDUSession_ToBeSetup_ItemIEs;
|
||||
// XNAP_PDUSessionResourcesToBeSetup_Item_t *PDUSession_ToBeSetup_Item;
|
||||
// X2AP_E_RABs_ToBeSetup_ItemIEs_t *e_RABS_ToBeSetup_ItemIEs;
|
||||
// X2AP_E_RABs_ToBeSetup_Item_t *e_RABs_ToBeSetup_Item;
|
||||
|
||||
xnap_gNB_instance_t *instance_p;
|
||||
xnap_gNB_data_t *xnap_gNB_data;
|
||||
MessageDef *msg;
|
||||
int ue_id;
|
||||
|
||||
DevAssert (pdu != NULL);
|
||||
xnHandoverRequest = &pdu->choice.initiatingMessage->value.choice.HandoverRequest;
|
||||
|
||||
if (stream == 0) {
|
||||
LOG_E (XNAP, "Received new xn handover request on stream == 0\n");
|
||||
/* TODO: send a xn failure response */
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOG_E (XNAP,"Received a new XN handover request\n");
|
||||
|
||||
xnap_gNB_data = xnap_get_gNB(NULL, assoc_id, 0);
|
||||
DevAssert(xnap_gNB_data != NULL);
|
||||
|
||||
instance_p = xnap_gNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
|
||||
msg = itti_alloc_new_message(TASK_XNAP, 0, XNAP_HANDOVER_REQ);
|
||||
|
||||
XNAP_FIND_PROTOCOLIE_BY_ID(XNAP_HandoverRequest_IEs_t, ie, xnHandoverRequest,
|
||||
XNAP_ProtocolIE_ID_id_oldNG_RANnodeUEXnAPID, true);
|
||||
if (ie == NULL ) {
|
||||
LOG_E (XNAP, "%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* allocate a new X2AP UE ID */
|
||||
ue_id = xnap_allocate_new_id(&instance_p->id_manager);
|
||||
if (ue_id == -1) {
|
||||
LOG_E (XNAP, "could not allocate a new XNAP UE ID\n");
|
||||
/* TODO: cancel handover: send HO preparation failure to source gNB */
|
||||
exit(1);
|
||||
}
|
||||
/* rnti is unknown yet, must not be set to -1, 0 is fine */
|
||||
xnap_set_ids(&instance_p->id_manager, ue_id, 0, ie->value.choice.NG_RANnodeUEXnAPID, ue_id);
|
||||
xnap_id_set_state(&instance_p->id_manager, ue_id, XNID_STATE_TARGET);
|
||||
|
||||
XNAP_HANDOVER_REQ(msg).ng_node_ue_xnap_id = ue_id;
|
||||
|
||||
XNAP_FIND_PROTOCOLIE_BY_ID(XNAP_HandoverRequest_IEs_t, ie, xnHandoverRequest,
|
||||
XNAP_ProtocolIE_ID_id_GUAMI, true);
|
||||
if (ie == NULL ) {
|
||||
LOG_E (XNAP, "%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
PLMNID_TO_MCC_MNC(&ie->value.choice.GUAMI.plmn_ID,
|
||||
XNAP_HANDOVER_REQ(msg).guami.plmn_id.mcc,
|
||||
XNAP_HANDOVER_REQ(msg).guami.plmn_id.mnc,
|
||||
XNAP_HANDOVER_REQ(msg).guami.plmn_id.mnc_digit_length);
|
||||
/* MCC_MNC_TO_PLMNID(xnHandoverRequest->GUAMI.plmn_ID.mcc,
|
||||
xnHandoverRequest->GUAMI.plmn_ID.mnc,
|
||||
xnHandoverRequest->GUAMI.plmn_ID.mnc_digit_length,
|
||||
&ie->value.choice.GUAMI.plmn_ID); **/
|
||||
|
||||
/** Need to understand if this search is neeeded **/
|
||||
XNAP_FIND_PROTOCOLIE_BY_ID(XNAP_HandoverRequest_IEs_t, ie, xnHandoverRequest,
|
||||
XNAP_ProtocolIE_ID_id_UEContextInfoHORequest, true);
|
||||
|
||||
if (ie == NULL ) {
|
||||
LOG_E (XNAP, "%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// XNAP_HANDOVER_REQ(msg).mme_ue_s1ap_id = ie->value.choice.UE_ContextInformation.mME_UE_S1AP_ID;
|
||||
|
||||
/* TODO: properly store Target Cell ID */
|
||||
|
||||
XNAP_HANDOVER_REQ(msg).ue_context.target_assoc_id = assoc_id;
|
||||
|
||||
XNAP_HANDOVER_REQ(msg).ue_context.security_capabilities.encryption_algorithms =
|
||||
BIT_STRING_to_uint16(&ie->value.choice.UEContextInfoHORequest.ueSecurityCapabilities.nr_EncyptionAlgorithms);
|
||||
XNAP_HANDOVER_REQ(msg).ue_context.security_capabilities.integrity_algorithms =
|
||||
BIT_STRING_to_uint16(&ie->value.choice.UEContextInfoHORequest.ueSecurityCapabilities.nr_IntegrityProtectionAlgorithms);
|
||||
|
||||
if ((ie->value.choice.UEContextInfoHORequest.securityInformation.key_NG_RAN_Star.buf) &&
|
||||
(ie->value.choice.UEContextInfoHORequest.securityInformation.key_NG_RAN_Star.size == 32)) {
|
||||
memcpy(XNAP_HANDOVER_REQ(msg).ue_context.as_security_key_ranstar, ie->value.choice.UEContextInfoHORequest.securityInformation.key_NG_RAN_Star.buf, 32);
|
||||
XNAP_HANDOVER_REQ(msg).ue_context.as_security_ncc = ie->value.choice.UEContextInfoHORequest.securityInformation.ncc;
|
||||
} else {
|
||||
LOG_E (XNAP,"Size of gNB key star does not match the expected value\n");
|
||||
}
|
||||
|
||||
/* if (ie->value.choice.UEContextInfoHORequest.pduSessionResourcesToBeSetup_List.list.count > 0) {
|
||||
|
||||
XNAP_HANDOVER_REQ(msg).ue_context.pdusession_tobe_setup_list.num_pdu = ie->value.choice.UEContextInfoHORequest.pduSessionResourcesToBeSetup_List.list.count;
|
||||
|
||||
for (int i=0;i<ie->value.choice.UEContextInfoHORequest.pduSessionResourcesToBeSetup_List.list.count;i++) {
|
||||
PDUSession_ToBeSetup_ItemIEs = (XNAP_PDUSessionResourcesToBeSetup_Item_t *) ie->value.choice.UE_ContextInfoHORequest.pduSessionResourcesToBeSetup_List.list.array[i];
|
||||
PDUSession_ToBeSetup_Item = &XNAP_PDUSessionResourcesToBeSetup_Item->value.choice.UE_ContextInfoHORequest.XNAP_PDUSessionResourcesToBeSetup_Item;
|
||||
|
||||
XNAP_HANDOVER_REQ(msg).ue_context.pdusession_tobe_setup_list.pdu[i].pdusession_id = PDUSession_ToBeSetup_Item->pduSessionId;
|
||||
|
||||
memcpy(XNAP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].eNB_addr.buffer,
|
||||
e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf,
|
||||
e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size);
|
||||
|
||||
XNAP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].eNB_addr.length =
|
||||
e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size * 8 - e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.bits_unused;
|
||||
|
||||
OCTET_STRING_TO_INT32(&e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.gTP_TEID,
|
||||
XNAP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].gtp_teid);
|
||||
|
||||
XNAP_HANDOVER_REQ(msg).e_rab_param[i].qos.qci = e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.qCI;
|
||||
XNAP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.priority_level = e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel;
|
||||
XNAP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability = e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability;
|
||||
XNAP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability = e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
LOG_E (XNAP,"Can't decode the qos allocation\n");
|
||||
}
|
||||
*/
|
||||
|
||||
// XNAP_RRC_Context_t *c = &ie->value.choice.UE_ContextInformation.rRC_Context;
|
||||
OCTET_STRING_t *c = &ie->value.choice.UEContextInfoHORequest.rrc_Context;
|
||||
if (sizeof(c) > 8192 /* TODO: this is the size of rrc_buffer in struct x2ap_handover_req_s */)
|
||||
{ printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); }
|
||||
|
||||
// memcpy(XNAP_HANDOVER_REQ(msg).ue_context.rrc_buffer, c, sizeof(c));
|
||||
XNAP_HANDOVER_REQ(msg).ue_context.rrc_buffer_size = sizeof(c);
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
39
openair2/XNAP/xnap_gNB_handler.h
Normal file
39
openair2/XNAP/xnap_gNB_handler.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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 xnap_gNB_handler.h
|
||||
* \brief xnap handler procedures for gNB
|
||||
* \date 2023 July
|
||||
* \version 1.0
|
||||
*/
|
||||
|
||||
#ifndef XNAP_GNB_HANDLERS_H_
|
||||
#define XNAP_GNB_HANDLERS_H_
|
||||
|
||||
#include "xnap_gNB_defs.h"
|
||||
|
||||
int xnap_gNB_handle_message(instance_t instance,
|
||||
sctp_assoc_t assoc_id,
|
||||
int32_t stream,
|
||||
const uint8_t *const data,
|
||||
const uint32_t data_length);
|
||||
|
||||
#endif /* XNAP_GNB_HANDLERS_H_ */
|
||||
338
openair2/XNAP/xnap_gNB_interface_management.c
Normal file
338
openair2/XNAP/xnap_gNB_interface_management.c
Normal file
@@ -0,0 +1,338 @@
|
||||
/*
|
||||
* 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 xnap_gNB_interface_management.c
|
||||
* \brief xnap handling interface procedures for gNB
|
||||
* \author Sreeshma Shiv <sreeshmau@iisc.ac.in>
|
||||
* \date Dec 2023
|
||||
* \version 1.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "intertask_interface.h"
|
||||
#include "xnap_common.h"
|
||||
#include "xnap_gNB_defs.h"
|
||||
#include "xnap_gNB_interface_management.h"
|
||||
#include "xnap_gNB_handler.h"
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
#include "XNAP_GlobalgNB-ID.h"
|
||||
#include "XNAP_ServedCells-NR-Item.h"
|
||||
#include "XNAP_NRFrequencyBandItem.h"
|
||||
#include "XNAP_GlobalNG-RANNode-ID.h"
|
||||
#include "XNAP_NRModeInfoFDD.h"
|
||||
#include "XNAP_NRModeInfoTDD.h"
|
||||
#include "XNAP_SupportedSULBandList.h"
|
||||
#include "XNAP_TAISupport-Item.h"
|
||||
#include "XNAP_BroadcastPLMNinTAISupport-Item.h"
|
||||
#include "xnap_gNB_management_procedures.h"
|
||||
|
||||
int xnap_gNB_handle_xn_setup_request(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, XNAP_XnAP_PDU_t *pdu)
|
||||
{
|
||||
XNAP_XnSetupRequest_t *xnSetupRequest;
|
||||
XNAP_XnSetupRequest_IEs_t *ie;
|
||||
// XNAP_ServedCells_NR_Item_t *servedCellMember;
|
||||
|
||||
DevAssert(pdu != NULL);
|
||||
xnSetupRequest = &pdu->choice.initiatingMessage->value.choice.XnSetupRequest;
|
||||
if (stream != 0) { /* Xn Setup: Non UE related procedure ->stream 0 */
|
||||
LOG_E(XNAP, "Received new XN setup request on stream != 0\n");
|
||||
/* Send a xn setup failure with protocol cause unspecified */
|
||||
MessageDef *message_p = itti_alloc_new_message(TASK_XNAP, 0, XNAP_SETUP_FAILURE);
|
||||
message_p->ittiMsgHeader.originInstance = assoc_id;
|
||||
xnap_setup_failure_t *fail = &XNAP_SETUP_FAILURE(message_p);
|
||||
fail->cause_type = XNAP_CAUSE_PROTOCOL;
|
||||
fail->cause_value = 6;
|
||||
itti_send_msg_to_task(TASK_XNAP, 0, message_p);
|
||||
}
|
||||
LOG_D(XNAP, "Received a new XN setup request\n");
|
||||
MessageDef *message_p = itti_alloc_new_message(TASK_XNAP, 0, XNAP_SETUP_REQ);
|
||||
message_p->ittiMsgHeader.originInstance = assoc_id;
|
||||
xnap_setup_req_t *req = &XNAP_SETUP_REQ(message_p);
|
||||
|
||||
// gNB_id
|
||||
XNAP_FIND_PROTOCOLIE_BY_ID(XNAP_XnSetupRequest_IEs_t, ie, xnSetupRequest, XNAP_ProtocolIE_ID_id_GlobalNG_RAN_node_ID, true);
|
||||
if (ie == NULL) {
|
||||
LOG_E(XNAP, "XNAP_ProtocolIE_ID_id_GlobalNG_RAN_node_ID is NULL pointer \n");
|
||||
return -1;
|
||||
} else {
|
||||
if (ie->value.choice.GlobalNG_RANNode_ID.choice.gNB->gnb_id.present == XNAP_GNB_ID_Choice_PR_gnb_ID) {
|
||||
// gNB ID = 28 bits
|
||||
uint8_t *gNB_id_buf = ie->value.choice.GlobalNG_RANNode_ID.choice.gNB->gnb_id.choice.gnb_ID.buf;
|
||||
if (ie->value.choice.GlobalNG_RANNode_ID.choice.gNB->gnb_id.choice.gnb_ID.size != 28) {
|
||||
// TODO: handle case where size != 28 -> notify ? reject ?
|
||||
}
|
||||
req->gNB_id = (gNB_id_buf[0] << 20) + (gNB_id_buf[1] << 12) + (gNB_id_buf[2] << 4) + ((gNB_id_buf[3] & 0xf0) >> 4);
|
||||
} else {
|
||||
// TODO if NSA setup
|
||||
}
|
||||
}
|
||||
LOG_D(XNAP, "Adding gNB to the list of associated gNBs: %lu\n", req->gNB_id);
|
||||
|
||||
XNAP_FIND_PROTOCOLIE_BY_ID(XNAP_XnSetupRequest_IEs_t, ie, xnSetupRequest, XNAP_ProtocolIE_ID_id_TAISupport_list, true);
|
||||
if (ie == NULL) {
|
||||
LOG_E(XNAP, "XNAP_ProtocolIE_ID_id_TAISupport_list is NULL pointer \n");
|
||||
return -1;
|
||||
} else {
|
||||
OCTET_STRING_TO_INT24(&ie->value.choice.TAISupport_List.list.array[0]->tac, req->tai_support);
|
||||
LOG_I(XNAP, "tac %d \n", req->tai_support);
|
||||
}
|
||||
LOG_D(XNAP, "req->gNB id: %lu \n", req->gNB_id);
|
||||
|
||||
LOG_D(XNAP, "Adding gNB to the list of associated gNBs\n");
|
||||
|
||||
XNAP_FIND_PROTOCOLIE_BY_ID(XNAP_XnSetupRequest_IEs_t, ie, xnSetupRequest, XNAP_ProtocolIE_ID_id_List_of_served_cells_NR, true);
|
||||
req->num_cells_available = ie->value.choice.ServedCells_NR.list.count;
|
||||
LOG_D(XNAP, "req->num_cells_available %d \n", req->num_cells_available);
|
||||
|
||||
for (int i = 0; i < req->num_cells_available; i++) {
|
||||
XNAP_ServedCellInformation_NR_t *servedCellMember =
|
||||
&(((XNAP_ServedCells_NR_Item_t *)ie->value.choice.ServedCells_NR.list.array[i])->served_cell_info_NR);
|
||||
req->info.nr_pci = servedCellMember->nrPCI;
|
||||
LOG_D(XNAP, "req->nr_pci[%d] %d \n", i, req->info.nr_pci);
|
||||
/* PLMN */
|
||||
PLMNID_TO_MCC_MNC(servedCellMember->broadcastPLMN.list.array[0],
|
||||
req->info.plmn.mcc,
|
||||
req->info.plmn.mnc,
|
||||
req->info.plmn.mnc_digit_length);
|
||||
BIT_STRING_TO_NR_CELL_IDENTITY(&servedCellMember->cellID.nr_CI, req->info.nr_cellid);
|
||||
LOG_D(XNAP,
|
||||
"[SCTP %d] Received BroadcastPLMN: MCC %d, MNC %d, CELL_ID %llu\n",
|
||||
assoc_id,
|
||||
req->info.plmn.mcc,
|
||||
req->info.plmn.mnc,
|
||||
(long long unsigned int)req->info.nr_cellid);
|
||||
// FDD Cells
|
||||
if (servedCellMember->nrModeInfo.present == XNAP_NRModeInfo_PR_fdd) {
|
||||
req->info.mode = XNAP_MODE_FDD;
|
||||
xnap_fdd_info_t *FDDs = &req->info.fdd;
|
||||
XNAP_NRModeInfoFDD_t *fdd_Info = servedCellMember->nrModeInfo.choice.fdd;
|
||||
FDDs->ul_freqinfo.arfcn = fdd_Info->ulNRFrequencyInfo.nrARFCN;
|
||||
AssertFatal(fdd_Info->ulNRFrequencyInfo.frequencyBand_List.list.count == 1, "cannot handle more than one frequency band\n");
|
||||
for (int f = 0; f < fdd_Info->ulNRFrequencyInfo.frequencyBand_List.list.count; f++) {
|
||||
XNAP_NRFrequencyBandItem_t *FreqItem = fdd_Info->ulNRFrequencyInfo.frequencyBand_List.list.array[f];
|
||||
FDDs->ul_freqinfo.band = FreqItem->nr_frequency_band;
|
||||
AssertFatal(FreqItem->supported_SUL_Band_List->list.count == 0, "cannot handle SUL bands!\n");
|
||||
}
|
||||
FDDs->dl_freqinfo.arfcn = fdd_Info->dlNRFrequencyInfo.nrARFCN;
|
||||
int dlBands = fdd_Info->dlNRFrequencyInfo.frequencyBand_List.list.count;
|
||||
AssertFatal(dlBands == 0, "cannot handle more than one frequency band\n");
|
||||
for (int dlB = 0; dlB < dlBands; dlB++) {
|
||||
XNAP_NRFrequencyBandItem_t *FreqItem = fdd_Info->dlNRFrequencyInfo.frequencyBand_List.list.array[dlB];
|
||||
FDDs->dl_freqinfo.band = FreqItem->nr_frequency_band;
|
||||
int num_available_supported_SULBands = FreqItem->supported_SUL_Band_List->list.count;
|
||||
AssertFatal(num_available_supported_SULBands == 0, "cannot handle SUL bands!\n");
|
||||
}
|
||||
FDDs->ul_tbw.scs = fdd_Info->ulNRTransmissonBandwidth.nRSCS;
|
||||
FDDs->ul_tbw.nrb = fdd_Info->ulNRTransmissonBandwidth.nRNRB;
|
||||
FDDs->dl_tbw.scs = fdd_Info->dlNRTransmissonBandwidth.nRSCS;
|
||||
FDDs->dl_tbw.nrb = fdd_Info->dlNRTransmissonBandwidth.nRNRB;
|
||||
} else if (servedCellMember->nrModeInfo.present == XNAP_NRModeInfo_PR_tdd) {
|
||||
req->info.mode = XNAP_MODE_TDD;
|
||||
xnap_tdd_info_t *TDDs = &req->info.tdd;
|
||||
XNAP_NRModeInfoTDD_t *tdd_Info = servedCellMember->nrModeInfo.choice.tdd;
|
||||
TDDs->freqinfo.arfcn = tdd_Info->nrFrequencyInfo.nrARFCN;
|
||||
AssertFatal(tdd_Info->nrFrequencyInfo.frequencyBand_List.list.count == 1, "cannot handle more than one frequency band\n");
|
||||
for (int f = 0; f < tdd_Info->nrFrequencyInfo.frequencyBand_List.list.count; f++) {
|
||||
XNAP_NRFrequencyBandItem_t *FreqItem = tdd_Info->nrFrequencyInfo.frequencyBand_List.list.array[f];
|
||||
TDDs->freqinfo.band = FreqItem->nr_frequency_band;
|
||||
}
|
||||
TDDs->tbw.scs = tdd_Info->nrTransmissonBandwidth.nRSCS;
|
||||
TDDs->tbw.nrb = tdd_Info->nrTransmissonBandwidth.nRNRB;
|
||||
} else {
|
||||
AssertFatal(false, "unknown NR Mode info \n");
|
||||
}
|
||||
}
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, instance, message_p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xnap_gNB_handle_xn_setup_response(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, XNAP_XnAP_PDU_t *pdu)
|
||||
{
|
||||
LOG_D(XNAP, "xnap_gNB_handle_xn_setup_response\n");
|
||||
AssertFatal(pdu->present == XNAP_XnAP_PDU_PR_successfulOutcome, "pdu->present != XNAP_XnAP_PDU_PR_successfulOutcome,\n");
|
||||
AssertFatal(pdu->choice.successfulOutcome->procedureCode == XNAP_ProcedureCode_id_xnSetup,
|
||||
"pdu->choice.successfulOutcome->procedureCode != XNAP_ProcedureCode_id_xnSetup\n");
|
||||
AssertFatal(pdu->choice.successfulOutcome->criticality == XNAP_Criticality_reject,
|
||||
"pdu->choice.successfulOutcome->criticality != XNAP_Criticality_reject\n");
|
||||
AssertFatal(pdu->choice.successfulOutcome->value.present == XNAP_SuccessfulOutcome__value_PR_XnSetupResponse,
|
||||
"pdu->choice.successfulOutcome->value.present != XNAP_SuccessfulOutcome__value_PR_XnSetupResponse\n");
|
||||
|
||||
XNAP_XnSetupResponse_t *xnSetupResponse = &pdu->choice.successfulOutcome->value.choice.XnSetupResponse;
|
||||
XNAP_XnSetupResponse_IEs_t *ie;
|
||||
uint32_t gNB_id = 0;
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_XNAP, 0, XNAP_SETUP_RESP);
|
||||
msg->ittiMsgHeader.originInstance = assoc_id;
|
||||
xnap_setup_resp_t *resp = &XNAP_SETUP_RESP(msg);
|
||||
xnap_gNB_instance_t *instance_p = xnap_gNB_get_instance(instance);
|
||||
xnap_gNB_data_t *xnap_gnb_data_p = xnap_get_gNB(instance, assoc_id);
|
||||
for (int i = 0; i < xnSetupResponse->protocolIEs.list.count; i++) {
|
||||
ie = xnSetupResponse->protocolIEs.list.array[i];
|
||||
|
||||
switch (ie->id) {
|
||||
case XNAP_ProtocolIE_ID_id_GlobalNG_RAN_node_ID:
|
||||
AssertFatal(ie->criticality == XNAP_Criticality_reject, "ie->criticality != XNAP_Criticality_reject\n");
|
||||
AssertFatal(ie->value.present == XNAP_XnSetupResponse_IEs__value_PR_GlobalNG_RANNode_ID,
|
||||
"ie->value.present != XNAP_XnSetupResponse_IEs__value_PR_GlobalNG_RANNode_ID\n");
|
||||
uint8_t *gNB_id_buf = ie->value.choice.GlobalNG_RANNode_ID.choice.gNB->gnb_id.choice.gnb_ID.buf;
|
||||
gNB_id = (gNB_id_buf[0] << 20) + (gNB_id_buf[1] << 12) + (gNB_id_buf[2] << 4) + ((gNB_id_buf[3] & 0xf0) >> 4);
|
||||
LOG_D(XNAP, "Connected gNB id: %07x\n", gNB_id);
|
||||
LOG_D(XNAP, "Adding gNB to the list of associated gNBs\n");
|
||||
xnap_gnb_data_p->state = XNAP_GNB_STATE_CONNECTED;
|
||||
xnap_gnb_data_p->gNB_id = gNB_id;
|
||||
break;
|
||||
case XNAP_ProtocolIE_ID_id_TAISupport_list:
|
||||
AssertFatal(ie->criticality == XNAP_Criticality_reject, "ie->criticality != XNAP_Criticality_reject\n");
|
||||
AssertFatal(ie->value.present == XNAP_XnSetupResponse_IEs__value_PR_TAISupport_List,
|
||||
"ie->value.present != XNAP_XnSetupResponse_IEs__value_PR_TAISupport_List\n");
|
||||
PLMNID_TO_MCC_MNC(&ie->value.choice.TAISupport_List.list.array[0]->broadcastPLMNs.list.array[0]->plmn_id,
|
||||
resp->info.plmn.mcc,
|
||||
resp->info.plmn.mnc,
|
||||
resp->info.plmn.mnc_digit_length);
|
||||
/*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;
|
||||
}
|
||||
}
|
||||
// XNAP_ServedCells_NR_Item_t *servedCellMember;
|
||||
|
||||
/* We received a new valid XN Setup Response on a stream != 0.
|
||||
* Reject gNB xn setup response.*/
|
||||
|
||||
/*if (stream != 0) {
|
||||
LOG_E(XNAP, "Received new xn setup response on stream != 0\n");
|
||||
}
|
||||
|
||||
if ((xnap_gNB_data = xnap_get_gNB(NULL, assoc_id)) == NULL) {
|
||||
LOG_E(XNAP,
|
||||
"[SCTP %d] Received XN setup response for non existing "
|
||||
"gNB context\n",
|
||||
assoc_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((xnap_gNB_data->state == XNAP_GNB_STATE_CONNECTED) || (xnap_gNB_data->state == XNAP_GNB_STATE_READY))
|
||||
|
||||
{
|
||||
LOG_E(XNAP, "Received Unexpexted XN Setup Response Message\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
LOG_D(XNAP, "Received a new XN setup response\n");
|
||||
|
||||
XNAP_FIND_PROTOCOLIE_BY_ID(XNAP_XnSetupResponse_IEs_t, ie, xnSetupResponse, XNAP_ProtocolIE_ID_id_GlobalNG_RAN_node_ID, true);
|
||||
|
||||
if (ie == NULL) {
|
||||
LOG_E(XNAP, "%s %d: ie is a NULL pointer \n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
}*/
|
||||
/* Set proper pci */
|
||||
XNAP_FIND_PROTOCOLIE_BY_ID(XNAP_XnSetupResponse_IEs_t, ie, xnSetupResponse, XNAP_ProtocolIE_ID_id_List_of_served_cells_NR, true);
|
||||
if (ie == NULL) {
|
||||
LOG_E(XNAP, "%s %d: ie is a NULL pointer \n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// if (ie->value.choice.ServedCells_NR.list.count > 0) {
|
||||
// servedCellMember = (XNAP_ServedCells_NR_Item_t *)ie->value.choice.ServedCells_NR.list.array[0];
|
||||
// xnap_gNB_data->Nid_cell = servedCellMember->served_cell_info_NR.nrPCI;
|
||||
// XNAP_SETUP_RESP(msg).info.nr_cellid = xnap_gNB_data->Nid_cell;
|
||||
//}
|
||||
|
||||
/* The association is now ready as source and target gNBs know parameters of each other.
|
||||
* Mark the association as connected */
|
||||
// xnap_gNB_data->state = XNAP_GNB_STATE_READY;
|
||||
|
||||
// instance_p = xnap_gNB_get_instance(instance);
|
||||
// DevAssert(instance_p != NULL);
|
||||
|
||||
instance_p->xn_target_gnb_associated_nb++;
|
||||
// xnap_handle_xn_setup_message(instance_p, xnap_gnb_data_p, 0);
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xnap_gNB_handle_xn_setup_failure(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, XNAP_XnAP_PDU_t *pdu)
|
||||
{
|
||||
DevAssert(pdu != NULL);
|
||||
XNAP_XnSetupFailure_t *xnSetupFailure;
|
||||
XNAP_XnSetupFailure_IEs_t *ie;
|
||||
|
||||
// xnap_gNB_instance_t *instance_p;
|
||||
xnap_gNB_data_t *xnap_gNB_data;
|
||||
|
||||
xnSetupFailure = &pdu->choice.unsuccessfulOutcome->value.choice.XnSetupFailure;
|
||||
|
||||
/*
|
||||
* We received a new valid XN Setup Failure on a stream != 0.
|
||||
* * * * This should not happen -> reject gNB xn setup failure.
|
||||
*/
|
||||
|
||||
if (stream != 0) {
|
||||
LOG_W(XNAP, "[SCTP %d] Received xn setup failure on stream != 0 (%d)\n", assoc_id, stream);
|
||||
}
|
||||
|
||||
if ((xnap_gNB_data = xnap_get_gNB(instance, assoc_id)) == NULL) {
|
||||
LOG_E(XNAP,
|
||||
"[SCTP %d] Received XN setup failure for non existing "
|
||||
"gNB context\n",
|
||||
assoc_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((xnap_gNB_data->state == XNAP_GNB_STATE_CONNECTED) || (xnap_gNB_data->state == XNAP_GNB_STATE_READY))
|
||||
|
||||
{
|
||||
LOG_E(XNAP, "Received Unexpexted XN Setup Failure Message\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
LOG_D(XNAP, "Received a new XN setup failure\n");
|
||||
|
||||
XNAP_FIND_PROTOCOLIE_BY_ID(XNAP_XnSetupFailure_IEs_t, ie, xnSetupFailure, XNAP_ProtocolIE_ID_id_Cause, true);
|
||||
|
||||
if (ie == NULL) {
|
||||
LOG_E(XNAP, "%s %d: ie is a NULL pointer \n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
if ((ie->value.choice.Cause.present == XNAP_Cause_PR_misc)
|
||||
&& (ie->value.choice.Cause.choice.misc == XNAP_CauseMisc_unspecified)) {
|
||||
LOG_E(XNAP, "Received XN setup failure for gNB ... gNB is not ready\n");
|
||||
exit(1);
|
||||
} else {
|
||||
LOG_E(XNAP, "Received xn setup failure for gNB... please check your parameters\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
xnap_gNB_data->state = XNAP_GNB_STATE_WAITING;
|
||||
|
||||
// instance_p = xnap_gNB_get_instance(instance);
|
||||
// DevAssert(instance_p != NULL);
|
||||
|
||||
xnap_handle_xn_setup_message(instance, assoc_id, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
36
openair2/XNAP/xnap_gNB_interface_management.h
Normal file
36
openair2/XNAP/xnap_gNB_interface_management.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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 xnap_gNB_interface_management.h
|
||||
* \brief xnap interface handler procedures for gNB
|
||||
* \date 2023 Dec
|
||||
* \version 1.0
|
||||
*/
|
||||
|
||||
#ifndef XNAP_GNB_INTERFACE_MANAGEMENT_H_
|
||||
#define XNAP_GNB_INTERFACE_MANAGEMENT_H_
|
||||
|
||||
/*Xn Setup*/
|
||||
int xnap_gNB_handle_xn_setup_request(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, XNAP_XnAP_PDU_t *pdu);
|
||||
int xnap_gNB_handle_xn_setup_response(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, XNAP_XnAP_PDU_t *pdu);
|
||||
int xnap_gNB_handle_xn_setup_failure(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, XNAP_XnAP_PDU_t *pdu);
|
||||
|
||||
#endif /* XNAP_GNB_INTERFACE_MANAGEMENT_H_ */
|
||||
40
openair2/XNAP/xnap_gNB_itti_messaging.c
Normal file
40
openair2/XNAP/xnap_gNB_itti_messaging.c
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 "intertask_interface.h"
|
||||
#include "xnap_gNB_itti_messaging.h"
|
||||
|
||||
void xnap_gNB_itti_send_sctp_data_req(sctp_assoc_t assoc_id, uint8_t *buffer, uint32_t buffer_length, uint16_t stream)
|
||||
{
|
||||
MessageDef *message_p;
|
||||
sctp_data_req_t *sctp_data_req;
|
||||
instance_t instance = 0; // we have only one instance
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_XNAP, 0, SCTP_DATA_REQ);
|
||||
sctp_data_req = &message_p->ittiMsg.sctp_data_req;
|
||||
|
||||
sctp_data_req->assoc_id = assoc_id;
|
||||
sctp_data_req->buffer = buffer;
|
||||
sctp_data_req->buffer_length = buffer_length;
|
||||
sctp_data_req->stream = stream;
|
||||
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
|
||||
}
|
||||
|
||||
33
openair2/XNAP/xnap_gNB_itti_messaging.h
Normal file
33
openair2/XNAP/xnap_gNB_itti_messaging.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 xnap_gNB_itti_messaging.h
|
||||
* \brief xnap itti messaging for gNB
|
||||
* \date 2023 July
|
||||
* \version 1.0
|
||||
*/
|
||||
|
||||
#ifndef XNAP_GNB_ITTI_MESSAGING_H_
|
||||
#define XNAP_GNB_ITTI_MESSAGING_H_
|
||||
|
||||
void xnap_gNB_itti_send_sctp_data_req(sctp_assoc_t assoc_id, uint8_t *buffer, uint32_t buffer_length, uint16_t stream);
|
||||
|
||||
#endif /* XNAP_GNB_ITTI_MESSAGING_H_ */
|
||||
184
openair2/XNAP/xnap_gNB_management_procedures.c
Normal file
184
openair2/XNAP/xnap_gNB_management_procedures.c
Normal file
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "intertask_interface.h"
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
#include "xnap_common.h"
|
||||
#include "xnap_gNB_defs.h"
|
||||
#include "xnap_gNB_task.h"
|
||||
|
||||
// xnap_gNB_internal_data_t xnap_gNB_internal_data;
|
||||
static xnap_gNB_instance_t *xn_inst[NUMBER_OF_gNB_MAX] = {0};
|
||||
|
||||
static int xnap_gNB_compare_assoc_id(const xnap_gNB_data_t *p1, const xnap_gNB_data_t *p2)
|
||||
{
|
||||
if (p1->assoc_id > p2->assoc_id)
|
||||
return 1;
|
||||
if (p1->assoc_id == p2->assoc_id)
|
||||
return 0;
|
||||
return -1; /* p1->assoc_id < p1->assoc_id */
|
||||
}
|
||||
|
||||
RB_GENERATE(xnap_gnb_tree, xnap_gNB_data_t, entry, xnap_gNB_compare_assoc_id);
|
||||
|
||||
/*int xnap_gNB_compare_assoc_id(struct xnap_gNB_data_s *p1, struct xnap_gNB_data_s *p2)
|
||||
{
|
||||
if (p1->assoc_id == -1) {
|
||||
if (p1->cnx_id < p2->cnx_id) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (p1->cnx_id > p2->cnx_id) {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if (p1->assoc_id < p2->assoc_id) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (p1->assoc_id > p2->assoc_id) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
static pthread_mutex_t xn_inst_mtx = PTHREAD_MUTEX_INITIALIZER;
|
||||
void createXninst(instance_t instanceP, xnap_setup_req_t *req, xnap_net_config_t *nc)
|
||||
{
|
||||
DevAssert(instanceP == 0);
|
||||
pthread_mutex_lock(&xn_inst_mtx);
|
||||
AssertFatal(xn_inst[0] == NULL, "Attempted to initialize multiple Xn instances\n");
|
||||
xn_inst[0] = calloc(1, sizeof(xnap_gNB_instance_t));
|
||||
AssertFatal(xn_inst[0] != NULL, "out of memory\n");
|
||||
if (req)
|
||||
xn_inst[0]->setup_req = *req;
|
||||
if (nc)
|
||||
xn_inst[0]->net_config = *nc;
|
||||
pthread_mutex_unlock(&xn_inst_mtx);
|
||||
}
|
||||
|
||||
void xnap_dump_trees(const instance_t instance)
|
||||
{
|
||||
pthread_mutex_lock(&xn_inst_mtx);
|
||||
printf("%ld connected gNBs \n", xn_inst[instance]->num_gnbs);
|
||||
xnap_gNB_data_t *xnap_gnb_data_p = NULL;
|
||||
/* cast is necessary to eliminate warning "discards ‘const’ qualifier" */
|
||||
RB_FOREACH (xnap_gnb_data_p, xnap_gnb_tree, &((xnap_gNB_instance_t *)xn_inst[instance])->xnap_gnbs) {
|
||||
if (xnap_gnb_data_p->assoc_id == -1) {
|
||||
printf("integrated gNB");
|
||||
printf("cnx_id %d\n", xnap_gnb_data_p->cnx_id);
|
||||
} else {
|
||||
printf("assoc_id %d", xnap_gnb_data_p->assoc_id);
|
||||
printf("state %d\n", xnap_gnb_data_p->state);
|
||||
printf("cnx_id %d\n", xnap_gnb_data_p->cnx_id);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&xn_inst_mtx);
|
||||
}
|
||||
|
||||
xnap_gNB_data_t *xnap_get_gNB(instance_t instance, sctp_assoc_t assoc_id)
|
||||
{
|
||||
AssertFatal(assoc_id != 0, "illegal assoc_id == 0: should be -1 or >0)\n");
|
||||
xnap_gNB_data_t e = {.assoc_id = assoc_id};
|
||||
pthread_mutex_lock(&xn_inst_mtx);
|
||||
xnap_gNB_data_t *xnap_gnb = RB_FIND(xnap_gnb_tree, &xn_inst[instance]->xnap_gnbs, &e);
|
||||
if (xnap_gnb == NULL) {
|
||||
LOG_W(NR_RRC, "no gNB connected or not found for assoc_id %d:\n", assoc_id);
|
||||
pthread_mutex_unlock(&xn_inst_mtx);
|
||||
return NULL;
|
||||
}
|
||||
pthread_mutex_unlock(&xn_inst_mtx);
|
||||
return xnap_gnb;
|
||||
}
|
||||
|
||||
xnap_gNB_instance_t *xnap_gNB_get_instance(instance_t instanceP)
|
||||
{
|
||||
DevAssert(instanceP == 0);
|
||||
pthread_mutex_lock(&xn_inst_mtx);
|
||||
xnap_gNB_instance_t *instance_xnap = xn_inst[instanceP];
|
||||
pthread_mutex_unlock(&xn_inst_mtx);
|
||||
return instance_xnap;
|
||||
}
|
||||
|
||||
sctp_assoc_t *xnap_gNB_get_assoc_id(instance_t instanceP)
|
||||
{
|
||||
DevAssert(instanceP == 0);
|
||||
pthread_mutex_lock(&xn_inst_mtx);
|
||||
sctp_assoc_t *xnap_assoc_id = xn_inst[instanceP];// xnap_assoc_id is not correct
|
||||
pthread_mutex_unlock(&xn_inst_mtx);
|
||||
return xnap_assoc_id;
|
||||
}
|
||||
|
||||
void xnap_insert_gnb(instance_t instance, xnap_gNB_data_t *xnap_gnb_data_p)
|
||||
{
|
||||
pthread_mutex_lock(&xn_inst_mtx);
|
||||
RB_INSERT(xnap_gnb_tree, &xn_inst[instance]->xnap_gnbs, xnap_gnb_data_p);
|
||||
xn_inst[instance]->num_gnbs++;
|
||||
pthread_mutex_unlock(&xn_inst_mtx);
|
||||
}
|
||||
|
||||
void xnap_handle_xn_setup_message(instance_t instance, sctp_assoc_t assoc_id, int sctp_shutdown)
|
||||
{
|
||||
if (sctp_shutdown) {
|
||||
/* A previously connected gNB has been shutdown */
|
||||
xnap_gNB_data_t *gnb_data_p = xnap_get_gNB(instance, assoc_id);
|
||||
if (gnb_data_p == NULL) {
|
||||
LOG_W(XNAP, "no gNB connected or not found for assoc_id %d:\n", assoc_id);
|
||||
return;
|
||||
}
|
||||
pthread_mutex_lock(&xn_inst_mtx);
|
||||
if (gnb_data_p->state == XNAP_GNB_STATE_CONNECTED) {
|
||||
gnb_data_p->state = XNAP_GNB_STATE_DISCONNECTED;
|
||||
// Removing the gNB data from tree
|
||||
RB_REMOVE(xnap_gnb_tree, &xn_inst[instance]->xnap_gnbs, gnb_data_p);
|
||||
if (xn_inst[instance]->xn_target_gnb_associated_nb > 0) {
|
||||
/* Decrease associated gNB number */
|
||||
xn_inst[instance]->xn_target_gnb_associated_nb--;
|
||||
}
|
||||
|
||||
/* If there are no more associated gNB */
|
||||
if (xn_inst[instance]->xn_target_gnb_associated_nb == 0) {
|
||||
// TODO : Inform GNB_APP ???
|
||||
LOG_I(XNAP, "No more associated gNBs- Number of connected gNBS : %d \n", xn_inst[instance]->xn_target_gnb_associated_nb);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Check that at least one setup message is pending */
|
||||
DevCheck(xn_inst[instance]->xn_target_gnb_pending_nb > 0, instance, xn_inst[instance]->xn_target_gnb_pending_nb, 0);
|
||||
|
||||
if (xn_inst[instance]->xn_target_gnb_pending_nb > 0) {
|
||||
/* Decrease pending messages number */
|
||||
xn_inst[instance]->xn_target_gnb_pending_nb--;
|
||||
}
|
||||
|
||||
/* If there are no more pending messages */
|
||||
if (xn_inst[instance]->xn_target_gnb_pending_nb == 0) {
|
||||
// TODO : Need to inform GNB_APP??
|
||||
LOG_I(XNAP, "No more pending messages- Number of connected gNBS : %d", xn_inst[instance]->xn_target_gnb_associated_nb);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&xn_inst_mtx);
|
||||
}
|
||||
|
||||
47
openair2/XNAP/xnap_gNB_management_procedures.h
Normal file
47
openair2/XNAP/xnap_gNB_management_procedures.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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 __XNAP_GNB_MANAGEMENT_PROCEDURES__H__
|
||||
#define __XNAP_GNB_MANAGEMENT_PROCEDURES__H__
|
||||
|
||||
// void xnap_gNB_prepare_internal_data(void);
|
||||
void createXninst(instance_t instanceP, xnap_setup_req_t *req, xnap_net_config_t *nc);
|
||||
// void xnap_dump_trees(void);
|
||||
void xnap_dump_trees(const instance_t instance);
|
||||
// void xnap_gNB_insert_new_instance(xnap_gNB_instance_t *new_instance_p);
|
||||
|
||||
xnap_gNB_instance_t *xnap_gNB_get_instance(instance_t instanceP);
|
||||
|
||||
sctp_assoc_t *xnap_gNB_get_assoc_id(instance_t instanceP);
|
||||
// uint16_t xnap_gNB_fetch_add_global_cnx_id(void);
|
||||
|
||||
// void xnap_gNB_prepare_internal_data(void);
|
||||
|
||||
// xnap_gNB_data_t *xnap_is_gNB_id_in_list(uint32_t gNB_id);
|
||||
|
||||
// xnap_gNB_data_t *xnap_is_gNB_assoc_id_in_list(uint32_t sctp_assoc_id);
|
||||
|
||||
// xnap_gNB_data_t *xnap_is_gNB_pci_in_list(const uint32_t pci);
|
||||
|
||||
xnap_gNB_data_t *xnap_get_gNB(instance_t instance, sctp_assoc_t assoc_id);
|
||||
void xnap_insert_gnb(instance_t instance, xnap_gNB_data_t *xnap_gnb_data_p);
|
||||
void xnap_handle_xn_setup_message(instance_t instance, sctp_assoc_t assoc_id, int sctp_shutdown);
|
||||
#endif /* __XNAP_GNB_MANAGEMENT_PROCEDURES__H__ */
|
||||
357
openair2/XNAP/xnap_gNB_task.c
Normal file
357
openair2/XNAP/xnap_gNB_task.c
Normal file
@@ -0,0 +1,357 @@
|
||||
/* 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 XNAP/xnap_gNB_task.c
|
||||
* \brief XNAP tasks and functions definitions
|
||||
* \author Sreeshma Shiv
|
||||
* \date Aug 2023
|
||||
* \version 1.0
|
||||
* \email: sreeshmau@iisc.ac.in
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "intertask_interface.h"
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
#include "xnap_gNB_task.h"
|
||||
#include "xnap_gNB_defs.h"
|
||||
#include "xnap_ids.h"
|
||||
#include "xnap_gNB_management_procedures.h"
|
||||
#include "xnap_gNB_handler.h"
|
||||
#include "xnap_gNB_generate_messages.h"
|
||||
#include "queue.h"
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
|
||||
// struct xnap_gnb_map;
|
||||
// struct xnap_gNB_data_s;
|
||||
|
||||
RB_PROTOTYPE(xnap_gnb_tree, xnap_gNB_data_t, entry, xnap_gNB_compare_assoc_id);
|
||||
|
||||
static void xnap_gNB_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind);
|
||||
|
||||
static void xnap_gNB_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind);
|
||||
|
||||
// static void xnap_gNB_handle_register_gNB(instance_t instance, xnap_register_gnb_req_t *xnap_register_gNB);
|
||||
|
||||
static void xnap_gNB_send_sctp_assoc_req(instance_t instance_p, xnap_net_config_t *nc, int index);
|
||||
static void xnap_gNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp);
|
||||
|
||||
static void xnap_gNB_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind)
|
||||
{
|
||||
int result;
|
||||
DevAssert(sctp_data_ind != NULL);
|
||||
xnap_gNB_handle_message(instance,
|
||||
sctp_data_ind->assoc_id,
|
||||
sctp_data_ind->stream,
|
||||
sctp_data_ind->buffer,
|
||||
sctp_data_ind->buffer_length);
|
||||
result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer);
|
||||
AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
}
|
||||
|
||||
static void xnap_gNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp)
|
||||
{
|
||||
xnap_gNB_instance_t *instance_xn = xnap_gNB_get_instance(instance); // managementproc;
|
||||
DevAssert(sctp_new_association_resp != NULL);
|
||||
DevAssert(instance_xn != NULL);
|
||||
/*Return if connection to gNB failed- to be modified if needed. (Exit on error in X2AP)*/
|
||||
if (sctp_new_association_resp->sctp_state == SCTP_STATE_UNREACHABLE) {
|
||||
LOG_E(XNAP,
|
||||
"association with gNB failed, is it running? If no, run it first. If yes, check IP addresses in your configuration "
|
||||
"file.\n");
|
||||
return;
|
||||
}
|
||||
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
|
||||
LOG_W(XNAP,
|
||||
"Received unsuccessful result for SCTP association state (%u), assoc_id (%d), instance %ld, cnx_id %u \n",
|
||||
sctp_new_association_resp->sctp_state,
|
||||
sctp_new_association_resp->assoc_id,
|
||||
instance,
|
||||
sctp_new_association_resp->ulp_cnx_id);
|
||||
xnap_handle_xn_setup_message(instance,
|
||||
sctp_new_association_resp->assoc_id,
|
||||
sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
|
||||
// sleep(3);
|
||||
// xnap_gNB_send_sctp_assoc_req(instance, &instance_xn->net_config, sctp_new_association_resp->ulp_cnx_id);
|
||||
return; // exit -1 for debugging
|
||||
}
|
||||
|
||||
xnap_gNB_data_t *xnap_gnb_data_p = calloc(1, sizeof(*xnap_gnb_data_p));
|
||||
AssertFatal(xnap_gnb_data_p != NULL, "out of memory\n");
|
||||
xnap_gnb_data_p->cnx_id = sctp_new_association_resp->ulp_cnx_id;
|
||||
xnap_gnb_data_p->assoc_id = sctp_new_association_resp->assoc_id;
|
||||
xnap_gnb_data_p->state = XNAP_GNB_STATE_WAITING;
|
||||
xnap_gnb_data_p->in_streams = sctp_new_association_resp->in_streams;
|
||||
xnap_gnb_data_p->out_streams = sctp_new_association_resp->out_streams;
|
||||
//xnap_dump_trees(instance);
|
||||
xnap_insert_gnb(instance, xnap_gnb_data_p);
|
||||
xnap_dump_trees(instance);
|
||||
xnap_gNB_generate_xn_setup_request(sctp_new_association_resp->assoc_id, &instance_xn->setup_req);
|
||||
}
|
||||
|
||||
int xnap_gNB_init_sctp(instance_t instance_p, xnap_net_config_t *nc)
|
||||
{
|
||||
// Create and alloc new message
|
||||
MessageDef *message;
|
||||
sctp_init_t *sctp_init = NULL;
|
||||
DevAssert(nc != NULL);
|
||||
message = itti_alloc_new_message(TASK_XNAP, 0, SCTP_INIT_MSG_MULTI_REQ);
|
||||
sctp_init = &message->ittiMsg.sctp_init_multi;
|
||||
sctp_init->port = nc->gnb_port_for_XNC;
|
||||
sctp_init->ppid = XNAP_SCTP_PPID;
|
||||
sctp_init->ipv4 = 1;
|
||||
sctp_init->ipv6 = 0;
|
||||
sctp_init->nb_ipv4_addr = 1;
|
||||
#if 0
|
||||
memcpy(&sctp_init->ipv4_address,
|
||||
nc->gnb_xn_ip_address,
|
||||
sizeof(*nc->gnb_xn_ip_address));
|
||||
#endif
|
||||
sctp_init->ipv4_address[0] = inet_addr(nc->gnb_xn_ip_address.ipv4_address);
|
||||
sctp_init->nb_ipv6_addr = 0;
|
||||
sctp_init->ipv6_address[0] = "0:0:0:0:0:0:0:1";
|
||||
return itti_send_msg_to_task(TASK_SCTP, instance_p, message);
|
||||
}
|
||||
|
||||
static void xnap_gNB_send_sctp_assoc_req(instance_t instance, xnap_net_config_t *nc, int index)
|
||||
{
|
||||
MessageDef *message = NULL;
|
||||
sctp_new_association_req_t *sctp_new_association_req = NULL;
|
||||
DevAssert(nc != NULL);
|
||||
message = itti_alloc_new_message(TASK_XNAP, 0, SCTP_NEW_ASSOCIATION_REQ);
|
||||
sctp_new_association_req = &message->ittiMsg.sctp_new_association_req;
|
||||
sctp_new_association_req->port = nc->gnb_port_for_XNC;
|
||||
sctp_new_association_req->ppid = XNAP_SCTP_PPID;
|
||||
sctp_new_association_req->in_streams = nc->sctp_streams.sctp_in_streams;
|
||||
sctp_new_association_req->out_streams = nc->sctp_streams.sctp_out_streams;
|
||||
|
||||
memcpy(&sctp_new_association_req->remote_address,
|
||||
&nc->target_gnb_xn_ip_address[index],
|
||||
sizeof(nc->target_gnb_xn_ip_address[index]));
|
||||
memcpy(&sctp_new_association_req->local_address, &nc->gnb_xn_ip_address, sizeof(nc->gnb_xn_ip_address));
|
||||
sctp_new_association_req->ulp_cnx_id = index;
|
||||
itti_send_msg_to_task(TASK_SCTP, instance, message);
|
||||
}
|
||||
|
||||
static void xnap_gNB_handle_sctp_init_msg_multi_cnf(instance_t instance, sctp_init_msg_multi_cnf_t *m)
|
||||
{
|
||||
xnap_gNB_instance_t *instance_xn = xnap_gNB_get_instance(instance);
|
||||
DevAssert(m != NULL);
|
||||
DevAssert(instance_xn != NULL);
|
||||
// instance->multi_sd = m->multi_sd;
|
||||
|
||||
/* Exit if CNF message reports failure.
|
||||
* Failure means multi_sd < 0.
|
||||
*/
|
||||
if (m->multi_sd < 0) {
|
||||
LOG_E(XNAP, "Error: be sure to properly configure XN in your configuration file.\n");
|
||||
DevAssert(m->multi_sd >= 0);
|
||||
}
|
||||
|
||||
/* Trying to connect to the provided list of gNB ip address */
|
||||
|
||||
for (int index = 0; index < instance_xn->net_config.nb_xn; index++) {
|
||||
LOG_I(XNAP, "gNB[%ld] gNB id %lx index %d acting as an initiator (client)\n", instance, instance_xn->setup_req.gNB_id, index);
|
||||
instance_xn->xn_target_gnb_pending_nb++;
|
||||
xnap_gNB_send_sctp_assoc_req(instance, &instance_xn->net_config, index);
|
||||
}
|
||||
}
|
||||
|
||||
static void xnap_gNB_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind)
|
||||
{
|
||||
xnap_gNB_instance_t *instance_p = xnap_gNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
xnap_gNB_data_t *xnap_gnb_data_p;
|
||||
DevAssert(sctp_new_association_ind != NULL);
|
||||
LOG_W(XNAP, "SCTP Association IND Received.\n");
|
||||
//xnap_dump_trees(instance);
|
||||
xnap_gnb_data_p = xnap_get_gNB(instance, sctp_new_association_ind->assoc_id);
|
||||
if (xnap_gnb_data_p == NULL) {
|
||||
LOG_W(XNAP, "xnap_gnb_data_p does not exist, creating new descriptor\n");
|
||||
/* TODO: Create new gNB descriptor-not yet associated? */
|
||||
xnap_gNB_data_t *xnap_gnb_data_p = calloc(1, sizeof(*xnap_gnb_data_p));
|
||||
AssertFatal(xnap_gnb_data_p != NULL, "out of memory\n");
|
||||
xnap_gnb_data_p->assoc_id = sctp_new_association_ind->assoc_id;
|
||||
xnap_gnb_data_p->state = XNAP_GNB_STATE_WAITING;
|
||||
xnap_gnb_data_p->in_streams = sctp_new_association_ind->in_streams;
|
||||
xnap_gnb_data_p->out_streams = sctp_new_association_ind->out_streams;
|
||||
//xnap_dump_trees(instance);
|
||||
xnap_insert_gnb(instance, xnap_gnb_data_p);
|
||||
xnap_dump_trees(instance);
|
||||
xnap_gnb_data_p->out_streams = sctp_new_association_ind->out_streams;
|
||||
LOG_W(XNAP, "Updated streams for assoc id: %d \n", sctp_new_association_ind->assoc_id);
|
||||
}
|
||||
xnap_dump_trees(instance);
|
||||
}
|
||||
|
||||
static
|
||||
void xnap_gNB_handle_handover_req(instance_t instance,
|
||||
xnap_handover_req_t *xnap_handover_req)
|
||||
{
|
||||
xnap_gNB_instance_t *instance_p;
|
||||
xnap_gNB_data_t *target;
|
||||
xnap_id_manager *id_manager;
|
||||
int ue_id;
|
||||
sctp_assoc_t assoc_id;
|
||||
//int target_pci = xnap_handover_req->target_physCellId; //pci or cgi?
|
||||
|
||||
instance_p = xnap_gNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
|
||||
// target = xnap_is_gNB_pci_in_list(target_pci);Write new function for this if needed
|
||||
DevAssert(target != NULL);
|
||||
|
||||
/* allocate xnap ID */
|
||||
id_manager = &instance_p->id_manager;
|
||||
ue_id = xnap_allocate_new_id(id_manager);
|
||||
MessageDef *message_p = itti_alloc_new_message(TASK_XNAP, 0, XNAP_HANDOVER_REQ);
|
||||
// message_p->ittiMsgHeader.originInstance = assoc_id;
|
||||
assoc_id = xnap_gNB_get_assoc_id(instance_p);
|
||||
xnap_handover_req_t *req = &XNAP_HANDOVER_REQ(message_p);
|
||||
if (ue_id == -1) {
|
||||
LOG_E(XNAP,"could not allocate a new XNAP UE ID\n");
|
||||
/* TODO: cancel handover: send (to be defined) message to RRC */
|
||||
exit(1);
|
||||
}
|
||||
/* id_source is ue_id, id_target is unknown yet */
|
||||
//xnap_set_ids(id_manager, ue_id, xnap_handover_req->rnti, ue_id, -1); //use?ho req structure wont have rnti- take from where it belongs to.
|
||||
//xnap_id_set_state(id_manager, ue_id, XNID_STATE_SOURCE_PREPARE);// use?
|
||||
//xnap_set_reloc_prep_timer(id_manager, ue_id,
|
||||
//xnap_timer_get_tti(&instance_p->timers));
|
||||
//xnap_id_set_target(id_manager, ue_id, target);
|
||||
|
||||
// xnap_gNB_generate_xn_handover_request(instance_p, target, xnap_handover_req, ue_id); //Review removed target here but needs it
|
||||
xnap_gNB_generate_xn_handover_request(assoc_id, xnap_handover_req);
|
||||
}
|
||||
|
||||
void *xnap_task(void *arg)
|
||||
{
|
||||
MessageDef *received_msg = NULL;
|
||||
int result;
|
||||
LOG_D(XNAP, "Starting XNAP layer\n");
|
||||
itti_mark_task_ready(TASK_XNAP);
|
||||
|
||||
while (1) {
|
||||
itti_receive_msg(TASK_XNAP, &received_msg);
|
||||
LOG_D(XNAP, "Received message %d:%s\n", ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
|
||||
switch (ITTI_MSG_ID(received_msg)) {
|
||||
case TERMINATE_MESSAGE:
|
||||
LOG_W(XNAP, "Exiting XNAP thread\n");
|
||||
itti_exit_task();
|
||||
break;
|
||||
|
||||
case XNAP_REGISTER_GNB_REQ: {
|
||||
xnap_setup_req_t *xnsetupmsg = &XNAP_REGISTER_GNB_REQ(received_msg).setup_req;
|
||||
xnap_net_config_t *xn_nc = &XNAP_REGISTER_GNB_REQ(received_msg).net_config;
|
||||
createXninst(ITTI_MSG_DESTINATION_INSTANCE(received_msg), xnsetupmsg, xn_nc);
|
||||
xnap_gNB_init_sctp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), xn_nc);
|
||||
} break;
|
||||
|
||||
case XNAP_SETUP_FAILURE: // from rrc/xnap
|
||||
xnap_gNB_generate_xn_setup_failure(ITTI_MSG_ORIGIN_INSTANCE(received_msg), &XNAP_SETUP_FAILURE(received_msg));
|
||||
break;
|
||||
|
||||
case XNAP_SETUP_RESP: // from rrc
|
||||
xnap_gNB_generate_xn_setup_response(ITTI_MSG_ORIGIN_INSTANCE(received_msg), &XNAP_SETUP_RESP(received_msg));
|
||||
break;
|
||||
|
||||
case XNAP_HANDOVER_REQ: // from rrc
|
||||
xnap_gNB_handle_handover_req(ITTI_MSG_ORIGIN_INSTANCE(received_msg),
|
||||
&XNAP_HANDOVER_REQ(received_msg));
|
||||
break;
|
||||
|
||||
case SCTP_INIT_MSG_MULTI_CNF:
|
||||
xnap_gNB_handle_sctp_init_msg_multi_cnf(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_init_msg_multi_cnf);
|
||||
break;
|
||||
|
||||
case SCTP_NEW_ASSOCIATION_RESP:
|
||||
xnap_gNB_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_new_association_resp);
|
||||
break;
|
||||
|
||||
case SCTP_NEW_ASSOCIATION_IND:
|
||||
xnap_gNB_handle_sctp_association_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_new_association_ind);
|
||||
break;
|
||||
|
||||
case SCTP_DATA_IND:
|
||||
xnap_gNB_handle_sctp_data_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_data_ind);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(XNAP, "Received unhandled message: %d:%s\n", ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
|
||||
break;
|
||||
}
|
||||
|
||||
result = itti_free(ITTI_MSG_ORIGIN_ID(received_msg), received_msg);
|
||||
AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
received_msg = NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#include "common/config/config_userapi.h"
|
||||
|
||||
int is_xnap_enabled(void)
|
||||
{
|
||||
static volatile int config_loaded = 0;
|
||||
static volatile int enabled = 0;
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
if (pthread_mutex_lock(&mutex))
|
||||
goto mutex_error;
|
||||
if (config_loaded) {
|
||||
if (pthread_mutex_unlock(&mutex))
|
||||
goto mutex_error;
|
||||
return enabled;
|
||||
}
|
||||
|
||||
char *enable_xn = NULL;
|
||||
paramdef_t p[] = {{"enable_xn", "yes/no", 0, .strptr = &enable_xn, .defstrval = "", TYPE_STRING, 0}};
|
||||
|
||||
/* TODO: do it per module - we check only first gNB */
|
||||
config_get(config_get_if(), p, sizeofArray(p), "gNBs.[0]");
|
||||
if (enable_xn != NULL && strcmp(enable_xn, "yes") == 0) {
|
||||
enabled = 1;
|
||||
}
|
||||
|
||||
/*Consider also the case of enabling XnAP for a gNB by parsing a gNB configuration file*/
|
||||
|
||||
config_get(config_get_if(), p, sizeofArray(p), "gNBs.[0]");
|
||||
if (enable_xn != NULL && strcmp(enable_xn, "yes") == 0) {
|
||||
enabled = 1;
|
||||
}
|
||||
|
||||
config_loaded = 1;
|
||||
|
||||
if (pthread_mutex_unlock(&mutex))
|
||||
goto mutex_error;
|
||||
return enabled;
|
||||
|
||||
mutex_error:
|
||||
LOG_E(XNAP, "mutex error\n");
|
||||
exit(1);
|
||||
}
|
||||
41
openair2/XNAP/xnap_gNB_task.h
Normal file
41
openair2/XNAP/xnap_gNB_task.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/* 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 <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef XNAP_H_
|
||||
#define XNAP_H_
|
||||
|
||||
#define XNAP_SCTP_PPID (61) ///< XNAP SCTP Payload Protocol Identifier (PPID)
|
||||
#include "xnap_gNB_defs.h"
|
||||
|
||||
int xnap_gNB_init_sctp(instance_t instance_p, xnap_net_config_t *nc);
|
||||
|
||||
void *xnap_task(void *arg);
|
||||
|
||||
int is_xnap_enabled(void);
|
||||
void xnap_trigger(void);
|
||||
|
||||
#endif /* XNAP_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
148
openair2/XNAP/xnap_ids.c
Normal file
148
openair2/XNAP/xnap_ids.c
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
/* Poornima */
|
||||
#include "xnap_ids.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void xnap_id_manager_init(xnap_id_manager *m)
|
||||
{
|
||||
int i;
|
||||
memset(m, 0, sizeof(xnap_id_manager));
|
||||
for (i = 0; i < XNAP_MAX_IDS; i++)
|
||||
m->ids[i].rnti = -1;
|
||||
}
|
||||
|
||||
int xnap_allocate_new_id(xnap_id_manager *m)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < XNAP_MAX_IDS; i++)
|
||||
if (m->ids[i].rnti == -1) {
|
||||
m->ids[i].rnti = 0;
|
||||
m->ids[i].id_source = -1;
|
||||
m->ids[i].id_target = -1;
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void xnap_release_id(xnap_id_manager *m, int id)
|
||||
{
|
||||
m->ids[id].rnti = -1;
|
||||
}
|
||||
|
||||
int xnap_find_id(xnap_id_manager *m, int id_source, int id_target)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < XNAP_MAX_IDS; i++)
|
||||
if (m->ids[i].rnti != -1 &&
|
||||
m->ids[i].id_source == id_source &&
|
||||
m->ids[i].id_target == id_target)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int xnap_find_id_from_id_source(xnap_id_manager *m, int id_source)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < XNAP_MAX_IDS; i++)
|
||||
if (m->ids[i].rnti != -1 &&
|
||||
m->ids[i].id_source == id_source)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int xnap_find_id_from_id_target(xnap_id_manager *m, int id_target)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < XNAP_MAX_IDS; i++)
|
||||
if (m->ids[i].rnti != -1 &&
|
||||
m->ids[i].id_target == id_target)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int xnap_find_id_from_rnti(xnap_id_manager *m, int rnti)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < XNAP_MAX_IDS; i++)
|
||||
if (m->ids[i].rnti == rnti)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void xnap_set_ids(xnap_id_manager *m, int ue_id, int rnti, int id_source, int id_target)
|
||||
{
|
||||
m->ids[ue_id].rnti = rnti;
|
||||
m->ids[ue_id].id_source = id_source;
|
||||
m->ids[ue_id].id_target = id_target;
|
||||
}
|
||||
|
||||
/* real type of target is xnap_gNB_data_t * */
|
||||
void xnap_id_set_target(xnap_id_manager *m, int ue_id, void *target)
|
||||
{
|
||||
m->ids[ue_id].target = target;
|
||||
}
|
||||
|
||||
void xnap_id_set_state(xnap_id_manager *m, int ue_id, xnid_state_t state)
|
||||
{
|
||||
m->ids[ue_id].state = state;
|
||||
}
|
||||
|
||||
void xnap_set_reloc_prep_timer(xnap_id_manager *m, int ue_id, uint64_t time)
|
||||
{
|
||||
m->ids[ue_id].t_reloc_prep_start = time;
|
||||
}
|
||||
|
||||
void xnap_set_reloc_overall_timer(xnap_id_manager *m, int ue_id, uint64_t time)
|
||||
{
|
||||
m->ids[ue_id].tx2_reloc_overall_start = time;
|
||||
}
|
||||
|
||||
void xnap_set_dc_prep_timer(xnap_id_manager *m, int ue_id, uint64_t time)
|
||||
{
|
||||
m->ids[ue_id].t_dc_prep_start = time;
|
||||
}
|
||||
|
||||
void xnap_set_dc_overall_timer(xnap_id_manager *m, int ue_id, uint64_t time)
|
||||
{
|
||||
m->ids[ue_id].t_dc_overall_start = time;
|
||||
}
|
||||
|
||||
int xnap_id_get_id_source(xnap_id_manager *m, int ue_id)
|
||||
{
|
||||
return m->ids[ue_id].id_source;
|
||||
}
|
||||
|
||||
int xnap_id_get_id_target(xnap_id_manager *m, int ue_id)
|
||||
{
|
||||
return m->ids[ue_id].id_target;
|
||||
}
|
||||
|
||||
int xnap_id_get_rnti(xnap_id_manager *m, int ue_id)
|
||||
{
|
||||
return m->ids[ue_id].rnti;
|
||||
}
|
||||
|
||||
void *xnap_id_get_target(xnap_id_manager *m, int ue_id)
|
||||
{
|
||||
return m->ids[ue_id].target;
|
||||
}
|
||||
87
openair2/XNAP/xnap_ids.h
Normal file
87
openair2/XNAP/xnap_ids.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
/* Poornima */
|
||||
#ifndef XNAP_IDS_H_
|
||||
#define XNAP_IDS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* maximum number of simultaneous handovers, do not set too high */
|
||||
#define XNAP_MAX_IDS 16
|
||||
|
||||
/*
|
||||
* state:
|
||||
* - when starting handover in source, UE is in state XNID_STATE_SOURCE_PREPARE
|
||||
* - after receiving HO_ack in source, UE is in state XNID_STATE_SOURCE_OVERALL
|
||||
* - in target, UE is in state XNID_STATE_TARGET
|
||||
* The state is used to check timers.
|
||||
*/
|
||||
typedef enum {
|
||||
XNID_STATE_SOURCE_PREPARE,
|
||||
XNID_STATE_SOURCE_OVERALL,
|
||||
XNID_STATE_TARGET,
|
||||
XNID_STATE_NSA_GNB_PREPARE,
|
||||
XNID_STATE_NSA_GNB_OVERALL,
|
||||
} xnid_state_t;
|
||||
|
||||
typedef struct {
|
||||
int rnti; /* -1 when free */
|
||||
int id_source;
|
||||
int id_target;
|
||||
|
||||
/* the target eNB. Real type is x2ap_eNB_data_t * */
|
||||
void *target;
|
||||
|
||||
/* state: needed to check timers */
|
||||
xnid_state_t state;
|
||||
|
||||
/* timers */
|
||||
uint64_t t_reloc_prep_start;
|
||||
uint64_t tx2_reloc_overall_start;
|
||||
uint64_t t_dc_prep_start;
|
||||
uint64_t t_dc_overall_start;
|
||||
} xnap_id;
|
||||
|
||||
typedef struct {
|
||||
xnap_id ids[XNAP_MAX_IDS];
|
||||
} xnap_id_manager;
|
||||
|
||||
void xnap_id_manager_init(xnap_id_manager *m);
|
||||
int xnap_allocate_new_id(xnap_id_manager *m);
|
||||
void xnap_release_id(xnap_id_manager *m, int id);
|
||||
int xnap_find_id(xnap_id_manager *, int id_source, int id_target);
|
||||
int xnap_find_id_from_id_source(xnap_id_manager *, int id_source);
|
||||
int xnap_find_id_from_id_target(xnap_id_manager *, int id_source);
|
||||
int xnap_find_id_from_rnti(xnap_id_manager *, int rnti);
|
||||
void xnap_set_ids(xnap_id_manager *m, int ue_id, int rnti, int id_source, int id_target);
|
||||
void xnap_id_set_state(xnap_id_manager *m, int ue_id, xnid_state_t state);
|
||||
/* real type of target is x2ap_eNB_data_t * */
|
||||
void xnap_id_set_target(xnap_id_manager *m, int ue_id, void *target);
|
||||
void xnap_set_reloc_prep_timer(xnap_id_manager *m, int ue_id, uint64_t time);
|
||||
void xnap_set_reloc_overall_timer(xnap_id_manager *m, int ue_id, uint64_t time);
|
||||
void xnap_set_dc_prep_timer(xnap_id_manager *m, int ue_id, uint64_t time);
|
||||
void xnap_set_dc_overall_timer(xnap_id_manager *m, int ue_id, uint64_t time);
|
||||
int xnap_id_get_id_source(xnap_id_manager *m, int ue_id);
|
||||
int xnap_id_get_id_target(xnap_id_manager *m, int ue_id);
|
||||
int xnap_id_get_rnti(xnap_id_manager *m, int ue_id);
|
||||
void *xnap_id_get_target(xnap_id_manager *m, int ue_id);
|
||||
|
||||
#endif /* X2AP_IDS_H_ */
|
||||
163
openair2/XNAP/xnap_timers.c
Normal file
163
openair2/XNAP/xnap_timers.c
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* 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 "xnap_timers.h"
|
||||
#include "assertions.h"
|
||||
#include "PHY/defs_common.h" /* TODO: try to not include this */
|
||||
#include "xnap_messages_types.h"
|
||||
#include "xnap_gNB_defs.h"
|
||||
#include "xnap_ids.h"
|
||||
#include "xnap_gNB_management_procedures.h"
|
||||
#include "xnap_gNB_generate_messages.h"
|
||||
|
||||
void xnap_timers_init(xnap_timers_t *t,
|
||||
int t_reloc_prep,
|
||||
int tx2_reloc_overall,
|
||||
int t_dc_prep,
|
||||
int t_dc_overall)
|
||||
{
|
||||
t->tti = 0;
|
||||
t->t_reloc_prep = t_reloc_prep;
|
||||
t->tx2_reloc_overall = tx2_reloc_overall;
|
||||
t->t_dc_prep = t_dc_prep;
|
||||
t->t_dc_overall = t_dc_overall;
|
||||
}
|
||||
/*
|
||||
void xnap_check_timers(instance_t instance)
|
||||
{
|
||||
xnap_gNB_instance_t *instance_p;
|
||||
xnap_timers_t *t;
|
||||
xnap_id_manager *m;
|
||||
int i;
|
||||
xnap_handover_cancel_cause_t cause;
|
||||
void *target;
|
||||
MessageDef *msg;
|
||||
int xnap_ongoing;
|
||||
|
||||
instance_p = xnap_gNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
|
||||
t = &instance_p->timers;
|
||||
m = &instance_p->id_manager;
|
||||
|
||||
// increment subframe count
|
||||
t->tti++;
|
||||
|
||||
xnap_ongoing = 0;
|
||||
|
||||
for (i = 0; i < XNAP_MAX_IDS; i++) {
|
||||
if (m->ids[i].rnti == -1) continue;
|
||||
|
||||
if (m->ids[i].state == XNAPID_STATE_SOURCE_PREPARE ||
|
||||
m->ids[i].state == XNAPID_STATE_SOURCE_OVERALL)
|
||||
xnap_ongoing++;
|
||||
|
||||
if (m->ids[i].state == XNAPID_STATE_SOURCE_PREPARE &&
|
||||
t->tti > m->ids[i].t_reloc_prep_start + t->t_reloc_prep) {
|
||||
LOG_I(XNAP, "XNAP timeout reloc prep\n");
|
||||
// t_reloc_prep timed out
|
||||
cause = XNAP_T_RELOC_PREP_TIMEOUT;
|
||||
goto xnap_handover_timeout;
|
||||
}
|
||||
|
||||
if (m->ids[i].state == XNAPID_STATE_SOURCE_OVERALL &&
|
||||
t->tti > m->ids[i].tx2_reloc_overall_start + t->tx2_reloc_overall) {
|
||||
LOG_I(XNAP, "XNAP timeout reloc overall\n");
|
||||
// tx2_reloc_overall timed out
|
||||
cause = XNAP_TX2_RELOC_OVERALL_TIMEOUT;
|
||||
goto xnap_handover_timeout;
|
||||
}
|
||||
|
||||
if (m->ids[i].state == XNAPID_STATE_NSA_GNB_PREPARE &&
|
||||
t->tti > m->ids[i].t_dc_prep_start + t->t_dc_prep) {
|
||||
int id_source;
|
||||
int id_target;
|
||||
|
||||
LOG_I(XNAP, "XNAP timeout DC prep\n");
|
||||
// t_dc_prep timed out
|
||||
target = xnap_id_get_target(m, i);
|
||||
id_source = xnap_id_get_id_source(m, i);
|
||||
id_target = xnap_id_get_id_target(m, i);
|
||||
xnap_gNB_generate_ENDC_xnap_SgNB_release_request(instance_p, target,
|
||||
id_source, id_target,
|
||||
XNAP_CAUSE_T_DC_PREP_TIMEOUT);
|
||||
|
||||
// inform RRC of timeout
|
||||
msg = itti_alloc_new_message(TASK_XNAP, 0, XNAP_ENDC_DC_PREP_TIMEOUT);
|
||||
XNAP_ENDC_DC_PREP_TIMEOUT(msg).rnti = xnap_id_get_rnti(m, i);
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg);
|
||||
|
||||
// remove UE from XNAP
|
||||
xnap_release_id(m, i);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m->ids[i].state == XNAPID_STATE_NSA_GNB_OVERALL &&
|
||||
t->tti > m->ids[i].t_dc_overall_start + t->t_dc_overall) {
|
||||
int id_source;
|
||||
int id_target;
|
||||
|
||||
LOG_I(XNAP, "XNAP timeout DC overall\n");
|
||||
// t_dc_overall timed out
|
||||
target = xnap_id_get_target(m, i);
|
||||
id_source = xnap_id_get_id_source(m, i);
|
||||
id_target = xnap_id_get_id_target(m, i);
|
||||
xnap_gNB_generate_ENDC_xnap_SgNB_release_required(instance_p, target,
|
||||
id_source, id_target, XNAP_CAUSE_T_DC_OVERALL_TIMEOUT);
|
||||
|
||||
// inform RRC of timeout
|
||||
msg = itti_alloc_new_message(TASK_XNAP, 0, XNAP_ENDC_DC_OVERALL_TIMEOUT);
|
||||
XNAP_ENDC_DC_OVERALL_TIMEOUT(msg).rnti = xnap_id_get_rnti(m, i);
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg);
|
||||
|
||||
// remove UE from X2AP
|
||||
xnap_release_id(m, i);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// no timeout -> check next UE
|
||||
continue;
|
||||
|
||||
xnap_handover_timeout:
|
||||
// inform target about timeout
|
||||
target = xnap_id_get_target(m, i);
|
||||
xnap_gNB_generate_xnap_handover_cancel(instance_p, target, i, cause);
|
||||
|
||||
// inform RRC of cancellation
|
||||
msg = itti_alloc_new_message(TASK_XNAP, 0, XNAP_HANDOVER_CANCEL);
|
||||
XNAP_HANDOVER_CANCEL(msg).rnti = xnap_id_get_rnti(m, i);
|
||||
XNAP_HANDOVER_CANCEL(msg).cause = cause;
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg);
|
||||
|
||||
// remove UE from XNAP
|
||||
xnap_release_id(m, i);
|
||||
}
|
||||
|
||||
if (xnap_ongoing && t->tti % 1000 == 0)
|
||||
LOG_I(XNAP, "XNAP has %d process ongoing\n", xnap_ongoing);
|
||||
}
|
||||
|
||||
uint64_t xnap_timer_get_tti(xnap_timers_t *t)
|
||||
{
|
||||
return t->tti;
|
||||
} **/
|
||||
51
openair2/XNAP/xnap_timers.h
Normal file
51
openair2/XNAP/xnap_timers.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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 XNAP_TIMERS_H_
|
||||
#define XNAP_TIMERS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
//#include "platform_types.h"
|
||||
|
||||
typedef struct {
|
||||
/* incremented every TTI (every millisecond when in realtime).
|
||||
* Used to check timers.
|
||||
* 64 bits gives us more than 500 million years of (realtime) processing.
|
||||
* It should be enough.
|
||||
*/
|
||||
uint64_t tti;
|
||||
|
||||
/* timer values (unit: TTI, ie. millisecond when in realtime) */
|
||||
int t_reloc_prep;
|
||||
int tx2_reloc_overall;
|
||||
int t_dc_prep;
|
||||
int t_dc_overall;
|
||||
} xnap_timers_t;
|
||||
|
||||
void xnap_timers_init(xnap_timers_t *t,
|
||||
int t_reloc_prep,
|
||||
int tx2_reloc_overall,
|
||||
int t_dc_prep,
|
||||
int t_dc_overall);
|
||||
//void xnap_check_timers(instance_t instance);
|
||||
uint64_t xnap_timer_get_tti(xnap_timers_t *t);
|
||||
|
||||
#endif /* X2AP_TIMERS_H_ */
|
||||
287
targets/PROJECTS/GENERIC-NR-5GC/CONF/Xnsetup_test_gNB1.conf
Normal file
287
targets/PROJECTS/GENERIC-NR-5GC/CONF/Xnsetup_test_gNB1.conf
Normal file
@@ -0,0 +1,287 @@
|
||||
Active_gNBs = ( "gNB-OAI");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_ID = 0xe00; //change gNB_ID for second gNB(XNAP)
|
||||
gNB_name = "gNB-OAI";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1; }) });
|
||||
|
||||
nr_cellid = 12345678L;
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
do_CSIRS = 1;
|
||||
do_SRS = 1;
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
physCellId = 0;
|
||||
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
|
||||
absoluteFrequencySSB = 641280;
|
||||
dl_frequencyBand = 78;
|
||||
# this is 3600 MHz
|
||||
dl_absoluteFrequencyPointA = 640008;
|
||||
#scs-SpecificCarrierList
|
||||
dl_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
dl_subcarrierSpacing = 1;
|
||||
dl_carrierBandwidth = 106;
|
||||
#initialDownlinkBWP
|
||||
#genericParameters
|
||||
# this is RBstart=27,L=48 (275*(L-1))+RBstart
|
||||
initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialDLBWPsubcarrierSpacing = 1;
|
||||
#pdcch-ConfigCommon
|
||||
initialDLBWPcontrolResourceSetZero = 12;
|
||||
initialDLBWPsearchSpaceZero = 0;
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 78;
|
||||
#scs-SpecificCarrierList
|
||||
ul_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
ul_subcarrierSpacing = 1;
|
||||
ul_carrierBandwidth = 106;
|
||||
pMax = 20;
|
||||
#initialUplinkBWP
|
||||
#genericParameters
|
||||
initialULBWPlocationAndBandwidth = 28875;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialULBWPsubcarrierSpacing = 1;
|
||||
#rach-ConfigCommon
|
||||
#rach-ConfigGeneric
|
||||
prach_ConfigurationIndex = 98;
|
||||
#prach_msg1_FDM
|
||||
#0 = one, 1=two, 2=four, 3=eight
|
||||
prach_msg1_FDM = 0;
|
||||
prach_msg1_FrequencyStart = 0;
|
||||
zeroCorrelationZoneConfig = 13;
|
||||
preambleReceivedTargetPower = -96;
|
||||
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
|
||||
preambleTransMax = 6;
|
||||
#powerRampingStep
|
||||
# 0=dB0,1=dB2,2=dB4,3=dB6
|
||||
powerRampingStep = 1;
|
||||
#ra_ReponseWindow
|
||||
#1,2,4,8,10,20,40,80
|
||||
ra_ResponseWindow = 4;
|
||||
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
|
||||
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
|
||||
#oneHalf (0..15) 4,8,12,16,...60,64
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14;
|
||||
#ra_ContentionResolutionTimer
|
||||
#(0..7) 8,16,24,32,40,48,56,64
|
||||
ra_ContentionResolutionTimer = 7;
|
||||
rsrp_ThresholdSSB = 19;
|
||||
#prach-RootSequenceIndex_PR
|
||||
#1 = 839, 2 = 139
|
||||
prach_RootSequenceIndex_PR = 2;
|
||||
prach_RootSequenceIndex = 1;
|
||||
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
|
||||
#
|
||||
msg1_SubcarrierSpacing = 1,
|
||||
# restrictedSetConfig
|
||||
# 0=unrestricted, 1=restricted type A, 2=restricted type B
|
||||
restrictedSetConfig = 0,
|
||||
|
||||
msg3_DeltaPreamble = 1;
|
||||
p0_NominalWithGrant =-90;
|
||||
|
||||
# pucch-ConfigCommon setup :
|
||||
# pucchGroupHopping
|
||||
# 0 = neither, 1= group hopping, 2=sequence hopping
|
||||
pucchGroupHopping = 0;
|
||||
hoppingId = 40;
|
||||
p0_nominal = -90;
|
||||
# ssb_PositionsInBurs_BitmapPR
|
||||
# 1=short, 2=medium, 3=long
|
||||
ssb_PositionsInBurst_PR = 2;
|
||||
ssb_PositionsInBurst_Bitmap = 1;
|
||||
|
||||
# ssb_periodicityServingCell
|
||||
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
|
||||
ssb_periodicityServingCell = 2;
|
||||
|
||||
# dmrs_TypeA_position
|
||||
# 0 = pos2, 1 = pos3
|
||||
dmrs_TypeA_Position = 0;
|
||||
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
subcarrierSpacing = 1;
|
||||
|
||||
|
||||
#tdd-UL-DL-ConfigurationCommon
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
referenceSubcarrierSpacing = 1;
|
||||
# pattern1
|
||||
# dl_UL_TransmissionPeriodicity
|
||||
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
|
||||
dl_UL_TransmissionPeriodicity = 6;
|
||||
nrofDownlinkSlots = 7;
|
||||
nrofDownlinkSymbols = 6;
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
|
||||
# ------- SCTP definitions
|
||||
SCTP :
|
||||
{
|
||||
# Number of streams to use in input/output
|
||||
SCTP_INSTREAMS = 2;
|
||||
SCTP_OUTSTREAMS = 2;
|
||||
};
|
||||
|
||||
|
||||
////////// AMF parameters:
|
||||
amf_ip_address = ( { ipv4 = "192.168.70.132";
|
||||
ipv6 = "192:168:30::17";
|
||||
active = "yes";
|
||||
preference = "ipv4";
|
||||
}
|
||||
);
|
||||
|
||||
///Xn
|
||||
enable_xn = "yes";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
txn_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
target_gnb_xn_ip_address = (
|
||||
{ ipv4 = "10.33.42.216";
|
||||
ipv6 = "192:168:30::17";
|
||||
preference = "ipv4";
|
||||
}
|
||||
);
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
GNB_INTERFACE_NAME_FOR_NG_AMF = "enp3s0";
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "10.33.42.214";
|
||||
GNB_INTERFACE_NAME_FOR_NGU = "enp3s0";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "10.33.42.214";
|
||||
GNB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
GNB_IPV4_ADDRESS_FOR_XNC = "10.33.42.214";
|
||||
GNB_PORT_FOR_XNC = 38422; # Spec 36422
|
||||
};
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
MACRLCs = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 150;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
ulsch_max_frame_inactivity = 0;
|
||||
ul_max_mcs = 28;
|
||||
}
|
||||
);
|
||||
|
||||
L1s = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
prach_dtx_threshold = 120;
|
||||
pucch0_dtx_threshold = 100;
|
||||
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
|
||||
}
|
||||
);
|
||||
|
||||
RUs = (
|
||||
{
|
||||
local_rf = "yes"
|
||||
nb_tx = 1
|
||||
nb_rx = 1
|
||||
att_tx = 12;
|
||||
att_rx = 12;
|
||||
bands = [78];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 114;
|
||||
eNB_instances = [0];
|
||||
#beamforming 1x4 matrix:
|
||||
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
|
||||
clock_src = "internal";
|
||||
}
|
||||
);
|
||||
|
||||
THREAD_STRUCT = (
|
||||
{
|
||||
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
|
||||
parallel_config = "PARALLEL_SINGLE_THREAD";
|
||||
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
|
||||
worker_config = "WORKER_ENABLE";
|
||||
}
|
||||
);
|
||||
|
||||
rfsimulator :
|
||||
{
|
||||
serveraddr = "server";
|
||||
serverport = "4043";
|
||||
options = (); #("saviq"); or/and "chanmod"
|
||||
modelname = "AWGN";
|
||||
IQfile = "/tmp/rfsimulator.iqs";
|
||||
};
|
||||
|
||||
security = {
|
||||
# preferred ciphering algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nea0, nea1, nea2, nea3
|
||||
ciphering_algorithms = ( "nea0" );
|
||||
|
||||
# preferred integrity algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nia0, nia1, nia2, nia3
|
||||
integrity_algorithms = ( "nia2", "nia0" );
|
||||
|
||||
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
|
||||
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
|
||||
drb_ciphering = "yes";
|
||||
drb_integrity = "no";
|
||||
};
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level ="info";
|
||||
hw_log_level ="info";
|
||||
phy_log_level ="info";
|
||||
mac_log_level ="info";
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
ngap_log_level ="debug";
|
||||
f1ap_log_level ="debug";
|
||||
};
|
||||
|
||||
e2_agent = {
|
||||
near_ric_ip_addr = "127.0.0.1";
|
||||
#sm_dir = "/path/where/the/SMs/are/located/"
|
||||
sm_dir = "/usr/local/lib/flexric/"
|
||||
};
|
||||
295
targets/PROJECTS/GENERIC-NR-5GC/CONF/Xnsetup_test_gNB2.conf
Normal file
295
targets/PROJECTS/GENERIC-NR-5GC/CONF/Xnsetup_test_gNB2.conf
Normal file
@@ -0,0 +1,295 @@
|
||||
Active_gNBs = ( "gNB-OAI");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_ID = 0xe01; //change gNB_ID for second gNB(XNAP)
|
||||
gNB_name = "gNB-OAI";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1; }) });
|
||||
|
||||
nr_cellid = 12345678L;
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
do_CSIRS = 1;
|
||||
do_SRS = 1;
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
physCellId = 0;
|
||||
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
|
||||
absoluteFrequencySSB = 641280;
|
||||
dl_frequencyBand = 78;
|
||||
# this is 3600 MHz
|
||||
dl_absoluteFrequencyPointA = 640008;
|
||||
#scs-SpecificCarrierList
|
||||
dl_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
dl_subcarrierSpacing = 1;
|
||||
dl_carrierBandwidth = 106;
|
||||
#initialDownlinkBWP
|
||||
#genericParameters
|
||||
# this is RBstart=27,L=48 (275*(L-1))+RBstart
|
||||
initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialDLBWPsubcarrierSpacing = 1;
|
||||
#pdcch-ConfigCommon
|
||||
initialDLBWPcontrolResourceSetZero = 12;
|
||||
initialDLBWPsearchSpaceZero = 0;
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 78;
|
||||
#scs-SpecificCarrierList
|
||||
ul_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
ul_subcarrierSpacing = 1;
|
||||
ul_carrierBandwidth = 106;
|
||||
pMax = 20;
|
||||
#initialUplinkBWP
|
||||
#genericParameters
|
||||
initialULBWPlocationAndBandwidth = 28875;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialULBWPsubcarrierSpacing = 1;
|
||||
#rach-ConfigCommon
|
||||
#rach-ConfigGeneric
|
||||
prach_ConfigurationIndex = 98;
|
||||
#prach_msg1_FDM
|
||||
#0 = one, 1=two, 2=four, 3=eight
|
||||
prach_msg1_FDM = 0;
|
||||
prach_msg1_FrequencyStart = 0;
|
||||
zeroCorrelationZoneConfig = 13;
|
||||
preambleReceivedTargetPower = -96;
|
||||
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
|
||||
preambleTransMax = 6;
|
||||
#powerRampingStep
|
||||
# 0=dB0,1=dB2,2=dB4,3=dB6
|
||||
powerRampingStep = 1;
|
||||
#ra_ReponseWindow
|
||||
#1,2,4,8,10,20,40,80
|
||||
ra_ResponseWindow = 4;
|
||||
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
|
||||
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
|
||||
#oneHalf (0..15) 4,8,12,16,...60,64
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14;
|
||||
#ra_ContentionResolutionTimer
|
||||
#(0..7) 8,16,24,32,40,48,56,64
|
||||
ra_ContentionResolutionTimer = 7;
|
||||
rsrp_ThresholdSSB = 19;
|
||||
#prach-RootSequenceIndex_PR
|
||||
#1 = 839, 2 = 139
|
||||
prach_RootSequenceIndex_PR = 2;
|
||||
prach_RootSequenceIndex = 1;
|
||||
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
|
||||
#
|
||||
msg1_SubcarrierSpacing = 1,
|
||||
# restrictedSetConfig
|
||||
# 0=unrestricted, 1=restricted type A, 2=restricted type B
|
||||
restrictedSetConfig = 0,
|
||||
|
||||
msg3_DeltaPreamble = 1;
|
||||
p0_NominalWithGrant =-90;
|
||||
|
||||
# pucch-ConfigCommon setup :
|
||||
# pucchGroupHopping
|
||||
# 0 = neither, 1= group hopping, 2=sequence hopping
|
||||
pucchGroupHopping = 0;
|
||||
hoppingId = 40;
|
||||
p0_nominal = -90;
|
||||
# ssb_PositionsInBurs_BitmapPR
|
||||
# 1=short, 2=medium, 3=long
|
||||
ssb_PositionsInBurst_PR = 2;
|
||||
ssb_PositionsInBurst_Bitmap = 1;
|
||||
|
||||
# ssb_periodicityServingCell
|
||||
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
|
||||
ssb_periodicityServingCell = 2;
|
||||
|
||||
# dmrs_TypeA_position
|
||||
# 0 = pos2, 1 = pos3
|
||||
dmrs_TypeA_Position = 0;
|
||||
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
subcarrierSpacing = 1;
|
||||
|
||||
|
||||
#tdd-UL-DL-ConfigurationCommon
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
referenceSubcarrierSpacing = 1;
|
||||
# pattern1
|
||||
# dl_UL_TransmissionPeriodicity
|
||||
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
|
||||
dl_UL_TransmissionPeriodicity = 6;
|
||||
nrofDownlinkSlots = 7;
|
||||
nrofDownlinkSymbols = 6;
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
|
||||
# ------- SCTP definitions
|
||||
SCTP :
|
||||
{
|
||||
# Number of streams to use in input/output
|
||||
SCTP_INSTREAMS = 2;
|
||||
SCTP_OUTSTREAMS = 2;
|
||||
};
|
||||
|
||||
|
||||
////////// AMF parameters:
|
||||
amf_ip_address = ( { ipv4 = "192.168.70.132";
|
||||
ipv6 = "192:168:30::17";
|
||||
active = "yes";
|
||||
preference = "ipv4";
|
||||
}
|
||||
);
|
||||
|
||||
///Xn
|
||||
enable_xn = "yes";
|
||||
target_gnb_xn_ip_address = (
|
||||
{ ipv4 = "10.33.42.107";
|
||||
ipv6 = "192:168:30::17";
|
||||
preference = "ipv4";
|
||||
},
|
||||
{ ipv4 = "10.33.42.213";
|
||||
ipv6 = "192:168:30::16";
|
||||
preference = "ipv4";
|
||||
},
|
||||
{ ipv4 = "10.33.42.219";
|
||||
ipv6 = "192:168:30::16";
|
||||
preference = "ipv4";
|
||||
},
|
||||
{ ipv4 = "10.33.42.217";
|
||||
ipv6 = "192:168:30::16";
|
||||
preference = "ipv4";
|
||||
}
|
||||
);
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
GNB_INTERFACE_NAME_FOR_NG_AMF = "enp3s0";
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "10.33.42.216";
|
||||
GNB_INTERFACE_NAME_FOR_NGU = "enp3s0";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "10.33.42.216";
|
||||
GNB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
GNB_IPV4_ADDRESS_FOR_XNC = "10.33.42.216";
|
||||
GNB_PORT_FOR_XNC = 38422; # Spec 38422
|
||||
};
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
MACRLCs = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 150;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
ulsch_max_frame_inactivity = 0;
|
||||
ul_max_mcs = 28;
|
||||
}
|
||||
);
|
||||
|
||||
L1s = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
prach_dtx_threshold = 120;
|
||||
pucch0_dtx_threshold = 100;
|
||||
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
|
||||
}
|
||||
);
|
||||
|
||||
RUs = (
|
||||
{
|
||||
local_rf = "yes"
|
||||
nb_tx = 1
|
||||
nb_rx = 1
|
||||
att_tx = 12;
|
||||
att_rx = 12;
|
||||
bands = [78];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 114;
|
||||
eNB_instances = [0];
|
||||
#beamforming 1x4 matrix:
|
||||
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
|
||||
clock_src = "internal";
|
||||
}
|
||||
);
|
||||
|
||||
THREAD_STRUCT = (
|
||||
{
|
||||
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
|
||||
parallel_config = "PARALLEL_SINGLE_THREAD";
|
||||
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
|
||||
worker_config = "WORKER_ENABLE";
|
||||
}
|
||||
);
|
||||
|
||||
rfsimulator :
|
||||
{
|
||||
serveraddr = "server";
|
||||
serverport = 4043;
|
||||
options = (); #("saviq"); or/and "chanmod"
|
||||
modelname = "AWGN";
|
||||
IQfile = "/tmp/rfsimulator.iqs";
|
||||
};
|
||||
|
||||
security = {
|
||||
# preferred ciphering algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nea0, nea1, nea2, nea3
|
||||
ciphering_algorithms = ( "nea0" );
|
||||
|
||||
# preferred integrity algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nia0, nia1, nia2, nia3
|
||||
integrity_algorithms = ( "nia2", "nia0" );
|
||||
|
||||
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
|
||||
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
|
||||
drb_ciphering = "yes";
|
||||
drb_integrity = "no";
|
||||
};
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level ="info";
|
||||
hw_log_level ="info";
|
||||
phy_log_level ="info";
|
||||
mac_log_level ="info";
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
ngap_log_level ="debug";
|
||||
f1ap_log_level ="debug";
|
||||
};
|
||||
|
||||
e2_agent = {
|
||||
near_ric_ip_addr = "127.0.0.1";
|
||||
#sm_dir = "/path/where/the/SMs/are/located/"
|
||||
sm_dir = "/usr/local/lib/flexric/"
|
||||
};
|
||||
Reference in New Issue
Block a user