Merge remote-tracking branch 'origin/nr-dual-connectivity' into NR_RRCConfiguration
This commit is contained in:
@@ -320,7 +320,7 @@ set (NR_RRC_ASN1_VERSION "NR_Rel15" )
|
||||
make_version(NR_RRC_VERSION 15 6 0)
|
||||
set (NR_RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/NR/MESSAGES/asn1c/ASN1_files/nr-rrc-15.6.0.asn1)
|
||||
add_definitions(-DNR_RRC_VERSION=${NR_RRC_VERSION})
|
||||
set (NR_RRC_FULL_DIR ${asn1_generated_dir}/${NR_RRC_ASN1_VERSION})
|
||||
set (NR_RRC_FULL_DIR ${asn1_generated_dir}/RRC_${NR_RRC_ASN1_VERSION})
|
||||
|
||||
# Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make
|
||||
execute_process(COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${NR_RRC_FULL_DIR}" "${NR_RRC_GRAMMAR}" "NR_" "-findirect-choice"
|
||||
@@ -1538,6 +1538,7 @@ set(L2_SRC
|
||||
${PDCP_DIR}/pdcp_netlink.c
|
||||
# ${RRC_DIR}/rrc_UE.c
|
||||
${RRC_DIR}/rrc_eNB.c
|
||||
${RRC_DIR}/rrc_eNB_endc.c
|
||||
${RRC_DIR}/rrc_eNB_S1AP.c
|
||||
${RRC_DIR}/rrc_eNB_UE_context.c
|
||||
${RRC_DIR}/rrc_common.c
|
||||
@@ -2332,7 +2333,7 @@ add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag)
|
||||
|
||||
target_link_libraries (lte-softmodem
|
||||
-Wl,--start-group
|
||||
RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB
|
||||
RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB
|
||||
PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7
|
||||
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB}
|
||||
-Wl,--end-group z dl)
|
||||
|
||||
@@ -223,7 +223,6 @@ int config_get(paramdef_t *params, int numparams, char *prefix) {
|
||||
}
|
||||
|
||||
configmodule_interface_t *cfgif = config_get_if();
|
||||
|
||||
if (cfgif != NULL) {
|
||||
ret = config_get_if()->get(params, numparams, prefix);
|
||||
|
||||
|
||||
@@ -86,6 +86,7 @@ unsigned short config_frames[4] = {2,9,11,13};
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "executables/thread-common.h"
|
||||
#include "NB_IoT_interface.h"
|
||||
#include "x2ap_eNB.h"
|
||||
|
||||
short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,16384,16384,-16384,-16384,16384,16384,16384,-16384,-16384,16384,-16384,-16384,7327,7327,7327,21981,21981,7327,21981,21981,7327,-7327,7327,-21981,21981,-7327,21981,-21981,-7327,7327,-7327,21981,-21981,7327,-21981,21981,-7327,-7327,-7327,-21981,-21981,-7327,-21981,-21981,10726,10726,10726,3576,3576,10726,3576,3576,10726,17876,10726,25027,3576,17876,3576,25027,17876,10726,17876,3576,25027,10726,25027,3576,17876,17876,17876,25027,25027,17876,25027,25027,10726,-10726,10726,-3576,3576,-10726,3576,-3576,10726,-17876,10726,-25027,3576,-17876,3576,-25027,17876,-10726,17876,-3576,25027,-10726,25027,-3576,17876,-17876,17876,-25027,25027,-17876,25027,-25027,-10726,10726,-10726,3576,-3576,10726,-3576,3576,-10726,17876,-10726,25027,-3576,17876,-3576,25027,-17876,10726,-17876,3576,-25027,10726,-25027,3576,-17876,17876,-17876,25027,-25027,17876,-25027,25027,-10726,-10726,-10726,-3576,-3576,-10726,-3576,-3576,-10726,-17876,-10726,-25027,-3576,-17876,-3576,-25027,-17876,-10726,-17876,-3576,-25027,-10726,-25027,-3576,-17876,-17876,-17876,-25027,-25027,-17876,-25027,-25027,8886,8886,8886,12439,12439,8886,12439,12439,8886,5332,8886,1778,12439,5332,12439,1778,5332,8886,5332,12439,1778,8886,1778,12439,5332,5332,5332,1778,1778,5332,1778,1778,8886,19547,8886,15993,12439,19547,12439,15993,8886,23101,8886,26655,12439,23101,12439,26655,5332,19547,5332,15993,1778,19547,1778,15993,5332,23101,5332,26655,1778,23101,1778,26655,19547,8886,19547,12439,15993,8886,15993,12439,19547,5332,19547,1778,15993,5332,15993,1778,23101,8886,23101,12439,26655,8886,26655,12439,23101,5332,23101,1778,26655,5332,26655,1778,19547,19547,19547,15993,15993,19547,15993,15993,19547,23101,19547,26655,15993,23101,15993,26655,23101,19547,23101,15993,26655,19547,26655,15993,23101,23101,23101,26655,26655,23101,26655,26655,8886,-8886,8886,-12439,12439,-8886,12439,-12439,8886,-5332,8886,-1778,12439,-5332,12439,-1778,5332,-8886,5332,-12439,1778,-8886,1778,-12439,5332,-5332,5332,-1778,1778,-5332,1778,-1778,8886,-19547,8886,-15993,12439,-19547,12439,-15993,8886,-23101,8886,-26655,12439,-23101,12439,-26655,5332,-19547,5332,-15993,1778,-19547,1778,-15993,5332,-23101,5332,-26655,1778,-23101,1778,-26655,19547,-8886,19547,-12439,15993,-8886,15993,-12439,19547,-5332,19547,-1778,15993,-5332,15993,-1778,23101,-8886,23101,-12439,26655,-8886,26655,-12439,23101,-5332,23101,-1778,26655,-5332,26655,-1778,19547,-19547,19547,-15993,15993,-19547,15993,-15993,19547,-23101,19547,-26655,15993,-23101,15993,-26655,23101,-19547,23101,-15993,26655,-19547,26655,-15993,23101,-23101,23101,-26655,26655,-23101,26655,-26655,-8886,8886,-8886,12439,-12439,8886,-12439,12439,-8886,5332,-8886,1778,-12439,5332,-12439,1778,-5332,8886,-5332,12439,-1778,8886,-1778,12439,-5332,5332,-5332,1778,-1778,5332,-1778,1778,-8886,19547,-8886,15993,-12439,19547,-12439,15993,-8886,23101,-8886,26655,-12439,23101,-12439,26655,-5332,19547,-5332,15993,-1778,19547,-1778,15993,-5332,23101,-5332,26655,-1778,23101,-1778,26655,-19547,8886,-19547,12439,-15993,8886,-15993,12439,-19547,5332,-19547,1778,-15993,5332,-15993,1778,-23101,8886,-23101,12439,-26655,8886,-26655,12439,-23101,5332,-23101,1778,-26655,5332,-26655,1778,-19547,19547,-19547,15993,-15993,19547,-15993,15993,-19547,23101,-19547,26655,-15993,23101,-15993,26655,-23101,19547,-23101,15993,-26655,19547,-26655,15993,-23101,23101,-23101,26655,-26655,23101,-26655,26655,-8886,-8886,-8886,-12439,-12439,-8886,-12439,-12439,-8886,-5332,-8886,-1778,-12439,-5332,-12439,-1778,-5332,-8886,-5332,-12439,-1778,-8886,-1778,-12439,-5332,-5332,-5332,-1778,-1778,-5332,-1778,-1778,-8886,-19547,-8886,-15993,-12439,-19547,-12439,-15993,-8886,-23101,-8886,-26655,-12439,-23101,-12439,-26655,-5332,-19547,-5332,-15993,-1778,-19547,-1778,-15993,-5332,-23101,-5332,-26655,-1778,-23101,-1778,-26655,-19547,-8886,-19547,-12439,-15993,-8886,-15993,-12439,-19547,-5332,-19547,-1778,-15993,-5332,-15993,-1778,-23101,-8886,-23101,-12439,-26655,-8886,-26655,-12439,-23101,-5332,-23101,-1778,-26655,-5332,-26655,-1778,-19547,-19547,-19547,-15993,-15993,-19547,-15993,-15993,-19547,-23101,-19547,-26655,-15993,-23101,-15993,-26655,-23101,-19547,-23101,-15993,-26655,-19547,-26655,-15993,-23101,-23101,-23101,-26655,-26655,-23101,-26655,-26655};
|
||||
|
||||
@@ -425,6 +426,18 @@ int create_gNB_tasks(uint32_t gnb_nb) {
|
||||
LOG_E(GNB_APP, "Create task for gNB APP failed\n");
|
||||
return -1;
|
||||
}
|
||||
if(itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0){
|
||||
LOG_E(SCTP, "Create task for SCTP failed\n");
|
||||
return -1;
|
||||
}
|
||||
if (is_x2ap_enabled()) {
|
||||
if(itti_create_task(TASK_X2AP, x2ap_task, NULL) < 0){
|
||||
LOG_E(X2AP, "Create task for X2AP failed\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG_I(X2AP, "X2AP is disabled.\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -84,9 +84,9 @@
|
||||
#else
|
||||
#define MAX_MOBILES_PER_ENB 4
|
||||
#define MAX_MOBILES_PER_ENB_NB_IoT 4
|
||||
#define MAX_MOBILES_PER_GNB 4
|
||||
#define MAX_eNB 2
|
||||
#define MAX_gNB 2
|
||||
#define MAX_MOBILES_PER_GNB 2//16
|
||||
#define MAX_eNB 2
|
||||
#define MAX_gNB 2
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
|
||||
@@ -81,7 +81,8 @@
|
||||
#ifndef OCP_FRAMEWORK
|
||||
typedef enum cell_type_e {
|
||||
CELL_MACRO_ENB,
|
||||
CELL_HOME_ENB
|
||||
CELL_HOME_ENB,
|
||||
CELL_MACRO_GNB
|
||||
} cell_type_t;
|
||||
|
||||
typedef enum paging_drx_e {
|
||||
@@ -272,6 +273,22 @@ typedef struct e_rab_setup_s {
|
||||
uint32_t gtp_teid;
|
||||
} e_rab_setup_t;
|
||||
|
||||
typedef struct e_rab_tobe_added_s {
|
||||
/* Unique e_rab_id for the UE. */
|
||||
uint8_t e_rab_id;
|
||||
|
||||
/* Unique drb_ID for the UE. */
|
||||
uint8_t drb_ID;
|
||||
|
||||
/* The transport layer address for the IP packets */
|
||||
transport_layer_addr_t eNB_addr;
|
||||
|
||||
/* S-GW Tunnel endpoint identifier */
|
||||
uint32_t gtp_teid;
|
||||
} e_rab_tobe_added_t;
|
||||
|
||||
|
||||
|
||||
typedef struct e_rab_tobeswitched_s {
|
||||
/* Unique e_rab_id for the UE. */
|
||||
uint8_t e_rab_id;
|
||||
|
||||
@@ -50,3 +50,8 @@ MESSAGE_DEF(X2AP_UE_CONTEXT_RELEASE , MESSAGE_PRIORITY_MED, x2ap_ue_
|
||||
|
||||
/*Senb bearer addition messages X2AP <-> RRC */
|
||||
MESSAGE_DEF(X2AP_SENB_ADDITION_REQ , MESSAGE_PRIORITY_MED, x2ap_senb_addition_req_t , x2ap_senb_addition_req)
|
||||
|
||||
/*SGnb bearer addition messages X2AP <-> RRC */
|
||||
MESSAGE_DEF(X2AP_ENDC_SGNB_ADDITION_REQ , MESSAGE_PRIORITY_MED, x2ap_ENDC_sgnb_addition_req_t , x2ap_ENDC_sgnb_addition_req)
|
||||
MESSAGE_DEF(X2AP_ENDC_SGNB_ADDITION_REQ_ACK , MESSAGE_PRIORITY_MED, x2ap_ENDC_sgnb_addition_req_ACK_t , x2ap_ENDC_sgnb_addition_req_ACK)
|
||||
MESSAGE_DEF(X2AP_ENDC_SGNB_RECONF_COMPLETE , MESSAGE_PRIORITY_MED, x2ap_ENDC_reconf_complete_t , x2ap_ENDC_sgnb_reconf_complete)
|
||||
|
||||
@@ -28,16 +28,19 @@
|
||||
//-------------------------------------------------------------------------------------------//
|
||||
// Defines to access message fields.
|
||||
|
||||
#define X2AP_REGISTER_ENB_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_req
|
||||
#define X2AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_req
|
||||
#define X2AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_resp
|
||||
#define X2AP_HANDOVER_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req
|
||||
#define X2AP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req_ack
|
||||
#define X2AP_REGISTER_ENB_CNF(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_cnf
|
||||
#define X2AP_DEREGISTERED_ENB_IND(mSGpTR) (mSGpTR)->ittiMsg.x2ap_deregistered_enb_ind
|
||||
#define X2AP_UE_CONTEXT_RELEASE(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ue_context_release
|
||||
#define X2AP_HANDOVER_CANCEL(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_cancel
|
||||
#define X2AP_SENB_ADDITION_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_senb_addition_req
|
||||
#define X2AP_REGISTER_ENB_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_req
|
||||
#define X2AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_req
|
||||
#define X2AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_resp
|
||||
#define X2AP_HANDOVER_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req
|
||||
#define X2AP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req_ack
|
||||
#define X2AP_REGISTER_ENB_CNF(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_cnf
|
||||
#define X2AP_DEREGISTERED_ENB_IND(mSGpTR) (mSGpTR)->ittiMsg.x2ap_deregistered_enb_ind
|
||||
#define X2AP_UE_CONTEXT_RELEASE(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ue_context_release
|
||||
#define X2AP_HANDOVER_CANCEL(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_cancel
|
||||
#define X2AP_SENB_ADDITION_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_senb_addition_req
|
||||
#define X2AP_ENDC_SGNB_ADDITION_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_addition_req
|
||||
#define X2AP_ENDC_SGNB_ADDITION_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_addition_req_ACK
|
||||
#define X2AP_ENDC_SGNB_RECONF_COMPLETE(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_reconf_complete
|
||||
|
||||
#define X2AP_MAX_NB_ENB_IP_ADDRESS 2
|
||||
|
||||
@@ -66,6 +69,13 @@ typedef enum {
|
||||
X2AP_TX2_RELOC_OVERALL_TIMEOUT
|
||||
} x2ap_handover_cancel_cause_t;
|
||||
|
||||
typedef enum {
|
||||
X2AP_RECONF_RESPONSE_SUCCESS,
|
||||
X2AP_RECONF_RESPONSE_REJECT
|
||||
/* Extensions may appear below */
|
||||
|
||||
} x2ap_sgNB_reconf_response_information_t;
|
||||
|
||||
typedef struct x2ap_handover_cancel_s {
|
||||
int rnti;
|
||||
x2ap_handover_cancel_cause_t cause;
|
||||
@@ -286,7 +296,7 @@ typedef struct x2ap_senb_addition_req_ack_s {
|
||||
|
||||
int MeNB_UE_X2_id;
|
||||
|
||||
int SeNB_UE_X2_id;
|
||||
int SgNB_UE_X2_id;
|
||||
|
||||
uint8_t nb_sCG_e_rabs_tobeadded;
|
||||
|
||||
@@ -303,4 +313,86 @@ typedef struct x2ap_senb_addition_req_ack_s {
|
||||
|
||||
} x2ap_senb_addition_req_ack_t;
|
||||
|
||||
typedef struct x2ap_ENDC_sgnb_addition_req_s {
|
||||
int ue_x2_id;
|
||||
|
||||
/* used for RRC->X2AP in source eNB */
|
||||
int rnti;
|
||||
|
||||
security_capabilities_t security_capabilities;
|
||||
|
||||
/* SgNB Security Key */
|
||||
uint8_t kgnb[32];
|
||||
|
||||
/*next_hop_chaining_coun */
|
||||
long int kgnb_ncc;
|
||||
|
||||
/* UE aggregate maximum bitrate */
|
||||
ambr_t ue_ambr;
|
||||
|
||||
uint8_t nb_e_rabs_tobeadded;
|
||||
|
||||
/* list of e_rab to be added by RRC layers */
|
||||
e_rab_tobe_added_t e_rabs_tobeadded[S1AP_MAX_E_RAB];
|
||||
|
||||
/* list of e_rab to be setup by RRC layers */
|
||||
e_rab_t e_rab_param[S1AP_MAX_E_RAB];
|
||||
|
||||
x2ap_lastvisitedcell_info_t lastvisitedcell_info;
|
||||
|
||||
uint8_t rrc_buffer[4096 /* arbitrary, big enough */];
|
||||
int rrc_buffer_size;
|
||||
|
||||
int target_assoc_id;
|
||||
|
||||
/*long int pDCPatSgNB = X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present;
|
||||
long int mCGresources = X2AP_EN_DC_ResourceConfiguration__mCGresources_not_present;
|
||||
long int sCGresources = X2AP_EN_DC_ResourceConfiguration__sCGresources_not_present;*/
|
||||
|
||||
|
||||
} x2ap_ENDC_sgnb_addition_req_t;
|
||||
|
||||
typedef struct x2ap_ENDC_sgnb_addition_req_ACK_s {
|
||||
int MeNB_ue_x2_id;
|
||||
|
||||
int SgNB_ue_x2_id;
|
||||
|
||||
/* used for X2AP->RRC in source eNB */
|
||||
int rnti;
|
||||
|
||||
uint8_t nb_e_rabs_admitted_tobeadded;
|
||||
|
||||
/* list of e_rab to be added by RRC layers */
|
||||
e_rab_tobe_added_t e_rabs_admitted_tobeadded[S1AP_MAX_E_RAB];
|
||||
|
||||
/* list of e_rab to be setup by RRC layers */
|
||||
e_rab_t e_rab_param[S1AP_MAX_E_RAB];
|
||||
|
||||
x2ap_lastvisitedcell_info_t lastvisitedcell_info;
|
||||
|
||||
uint8_t rrc_buffer[4096 /* arbitrary, big enough */];
|
||||
int rrc_buffer_size;
|
||||
|
||||
int target_assoc_id;
|
||||
|
||||
/*long int pDCPatSgNB = X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present;
|
||||
long int mCGresources = X2AP_EN_DC_ResourceConfiguration__mCGresources_not_present;
|
||||
long int sCGresources = X2AP_EN_DC_ResourceConfiguration__sCGresources_not_present;*/
|
||||
|
||||
|
||||
} x2ap_ENDC_sgnb_addition_req_ACK_t;
|
||||
|
||||
typedef struct x2ap_ENDC_reconf_complete_s {
|
||||
int MeNB_ue_x2_id;
|
||||
|
||||
int SgNB_ue_x2_id;
|
||||
|
||||
x2ap_sgNB_reconf_response_information_t reconf_response;
|
||||
|
||||
uint8_t rrc_buffer[4096 /* arbitrary, big enough */];
|
||||
int rrc_buffer_size;
|
||||
|
||||
} x2ap_ENDC_reconf_complete_t;
|
||||
|
||||
|
||||
#endif /* X2AP_MESSAGES_TYPES_H_ */
|
||||
|
||||
@@ -2124,6 +2124,11 @@ int RCconfig_S1(
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_ENB;
|
||||
} else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_HOME_ENB") == 0) {
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB;
|
||||
// Temporary option to be able to parse an eNB configuration file which is treated as gNB from
|
||||
// the X2AP layer and test the setup of an ENDC X2AP connection. To be removed when we are ready to
|
||||
// parse an actual gNB configuration file wrt. the X2AP parameters instead.
|
||||
} else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_GNB") == 0) {
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_GNB;
|
||||
} else {
|
||||
AssertFatal(0,
|
||||
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n",
|
||||
@@ -2353,7 +2358,7 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_ENB;
|
||||
} else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_HOME_ENB") == 0) {
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB;
|
||||
} else {
|
||||
}else {
|
||||
AssertFatal (0,
|
||||
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n",
|
||||
RC.config_file_name, i, *(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr));
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
# endif
|
||||
|
||||
# include "PHY/INIT/phy_init.h"
|
||||
|
||||
# include "x2ap_eNB.h"
|
||||
extern unsigned char NB_gNB_INST;
|
||||
#endif
|
||||
|
||||
@@ -115,16 +115,38 @@ static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//,
|
||||
}
|
||||
# endif
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
static uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end) {
|
||||
uint32_t gnb_id;
|
||||
MessageDef *msg_p;
|
||||
uint32_t register_gnb_x2_pending = 0;
|
||||
|
||||
for (gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) {
|
||||
{
|
||||
msg_p = itti_alloc_new_message (TASK_GNB_APP, X2AP_REGISTER_ENB_REQ);
|
||||
LOG_I(X2AP, "GNB_ID: %d \n", gnb_id);
|
||||
RCconfig_NR_X2(msg_p, gnb_id);
|
||||
itti_send_msg_to_task (TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p);
|
||||
register_gnb_x2_pending++;
|
||||
}
|
||||
}
|
||||
|
||||
return register_gnb_x2_pending;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
void *gNB_app_task(void *args_p)
|
||||
{
|
||||
|
||||
#if defined(ENABLE_ITTI)
|
||||
uint32_t gnb_nb = RC.nb_nr_inst;
|
||||
uint32_t gnb_id_start = 0;
|
||||
uint32_t gnb_id_end = gnb_id_start + gnb_nb;
|
||||
uint32_t x2_register_gnb_pending = 0;
|
||||
# if defined(ENABLE_USE_MME)
|
||||
//uint32_t register_gnb_pending;
|
||||
//uint32_t registered_gnb;
|
||||
@@ -166,6 +188,12 @@ void *gNB_app_task(void *args_p)
|
||||
configure_nr_rrc(gnb_id);
|
||||
}
|
||||
|
||||
if (is_x2ap_enabled() ) { //&& !NODE_IS_DU(RC.rrc[0]->node_type)
|
||||
LOG_I(X2AP, "X2AP enabled \n");
|
||||
x2_register_gnb_pending = gNB_app_register_x2 (gnb_id_start, gnb_id_end);
|
||||
|
||||
}
|
||||
|
||||
# if defined(ENABLE_USE_MME)
|
||||
/* Try to register each gNB */
|
||||
//registered_gnb = 0;
|
||||
|
||||
@@ -977,3 +977,188 @@ void NRRCConfig(void) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) {
|
||||
int J, l;
|
||||
char *address = NULL;
|
||||
char *cidr = NULL;
|
||||
|
||||
//int num_gnbs = 0;
|
||||
//int num_component_carriers = 0;
|
||||
int j,k = 0;
|
||||
int32_t gnb_id = 0;
|
||||
|
||||
paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
|
||||
paramdef_t GNBParams[] = GNBPARAMS_DESC;
|
||||
paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0};
|
||||
/* get global parameters, defined outside any section in the config file */
|
||||
config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL);
|
||||
|
||||
//paramlist_def_t SCCsParamList = {GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, NULL, 0};
|
||||
|
||||
AssertFatal(i < GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt,
|
||||
"Failed to parse config file %s, %uth attribute %s \n",
|
||||
RC.config_file_name, i, ENB_CONFIG_STRING_ACTIVE_ENBS);
|
||||
|
||||
if (GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt > 0) {
|
||||
// Output a list of all gNBs.
|
||||
config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL);
|
||||
|
||||
if (GNBParamList.numelt > 0) {
|
||||
for (k = 0; k < GNBParamList.numelt; k++) {
|
||||
if (GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr == NULL) {
|
||||
// Calculate a default eNB ID
|
||||
if (EPC_MODE_ENABLED) {
|
||||
uint32_t hash;
|
||||
hash = s1ap_generate_eNB_id ();
|
||||
gnb_id = k + (hash & 0xFFFF8);
|
||||
} else {
|
||||
gnb_id = k;
|
||||
}
|
||||
} else {
|
||||
gnb_id = *(GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr);
|
||||
}
|
||||
|
||||
// search if in active list
|
||||
for (j = 0; j < GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt; j++) {
|
||||
if (strcmp(GNBSParams[GNB_ACTIVE_GNBS_IDX].strlistptr[j], *(GNBParamList.paramarray[k][GNB_GNB_NAME_IDX].strptr)) == 0) {
|
||||
paramdef_t PLMNParams[] = GNBPLMNPARAMS_DESC;
|
||||
paramlist_def_t PLMNParamList = {GNB_CONFIG_STRING_PLMN_LIST, NULL, 0};
|
||||
/* 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]);
|
||||
|
||||
paramdef_t X2Params[] = X2PARAMS_DESC;
|
||||
paramlist_def_t X2ParamList = {ENB_CONFIG_STRING_TARGET_ENB_X2_IP_ADDRESS,NULL,0};
|
||||
paramdef_t SCTPParams[] = GNBSCTPPARAMS_DESC;
|
||||
paramdef_t NETParams[] = GNBNETPARAMS_DESC;
|
||||
/* TODO: fix the size - if set lower we have a crash (MAX_OPTNAME_SIZE was 64 when this code was written) */
|
||||
/* this is most probably a problem with the config module */
|
||||
char aprefix[MAX_OPTNAME_SIZE*80 + 8];
|
||||
sprintf(aprefix,"%s.[%i]",GNB_CONFIG_STRING_GNB_LIST,k);
|
||||
/* Some default/random parameters */
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).eNB_id = gnb_id;
|
||||
|
||||
if (strcmp(*(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr), "CELL_MACRO_GNB") == 0) {
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_GNB;
|
||||
}else {
|
||||
AssertFatal (0,
|
||||
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n",
|
||||
RC.config_file_name, i, *(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr));
|
||||
}
|
||||
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(GNBParamList.paramarray[k][GNB_GNB_NAME_IDX].strptr));
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).tac = *GNBParamList.paramarray[k][GNB_TRACKING_AREA_CODE_IDX].uptr;
|
||||
config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix);
|
||||
|
||||
if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6)
|
||||
AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n",
|
||||
PLMNParamList.numelt);
|
||||
|
||||
if (PLMNParamList.numelt > 1)
|
||||
LOG_W(X2AP, "X2AP currently handles only one PLMN, ignoring the others!\n");
|
||||
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).mcc = *PLMNParamList.paramarray[0][GNB_MOBILE_COUNTRY_CODE_IDX].uptr;
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).mnc = *PLMNParamList.paramarray[0][GNB_MOBILE_NETWORK_CODE_IDX].uptr;
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length = *PLMNParamList.paramarray[0][GNB_MNC_DIGIT_LENGTH].u8ptr;
|
||||
AssertFatal(X2AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length == 3
|
||||
|| X2AP_REGISTER_ENB_REQ(msg_p).mnc < 100,
|
||||
"MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n",
|
||||
X2AP_REGISTER_ENB_REQ(msg_p).mnc);
|
||||
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).num_cc = 1;
|
||||
J = 0;
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).eutra_band[J] = 78; //ccparams_nr_x2.nr_band; //78
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).downlink_frequency[J] = 3600000000; //ccparams_nr_x2.downlink_frequency; //3600000000
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = 0; //(unsigned int) ccparams_nr_x2.uplink_frequency_offset; //0
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= 0; //ccparams_nr_x2.Nid_cell; //0
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= 106; //ccparams_nr_x2.N_RB_DL; //106
|
||||
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD;
|
||||
|
||||
//Temp out
|
||||
/*X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_DL[J] = to_earfcn_DL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency, ccparams_lte.N_RB_DL);
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_UL[J] = to_earfcn_UL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency + ccparams_lte.uplink_frequency_offset, ccparams_lte.N_RB_DL);*/
|
||||
|
||||
sprintf(aprefix,"%s.[%i]",GNB_CONFIG_STRING_GNB_LIST,k);
|
||||
config_getlist( &X2ParamList,X2Params,sizeof(X2Params)/sizeof(paramdef_t),aprefix);
|
||||
AssertFatal(X2ParamList.numelt <= X2AP_MAX_NB_ENB_IP_ADDRESS,
|
||||
"value of X2ParamList.numelt %d must be lower than X2AP_MAX_NB_ENB_IP_ADDRESS %d value: reconsider to increase X2AP_MAX_NB_ENB_IP_ADDRESS\n",
|
||||
X2ParamList.numelt,X2AP_MAX_NB_ENB_IP_ADDRESS);
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 = 0;
|
||||
|
||||
for (l = 0; l < X2ParamList.numelt; l++) {
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 += 1;
|
||||
strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4_address,*(X2ParamList.paramarray[l][ENB_X2_IPV4_ADDRESS_IDX].strptr));
|
||||
strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6_address,*(X2ParamList.paramarray[l][ENB_X2_IPV6_ADDRESS_IDX].strptr));
|
||||
|
||||
if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) {
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 1;
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 0;
|
||||
} else if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) {
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 0;
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 1;
|
||||
} else if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) {
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 1;
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// timers
|
||||
{
|
||||
int t_reloc_prep = 0;
|
||||
int tx2_reloc_overall = 0;
|
||||
paramdef_t p[] = {
|
||||
{ "t_reloc_prep", "t_reloc_prep", 0, iptr:&t_reloc_prep, defintval:0, TYPE_INT, 0 },
|
||||
{ "tx2_reloc_overall", "tx2_reloc_overall", 0, iptr:&tx2_reloc_overall, defintval:0, TYPE_INT, 0 }
|
||||
};
|
||||
config_get(p, sizeof(p)/sizeof(paramdef_t), aprefix);
|
||||
|
||||
if (t_reloc_prep <= 0 || t_reloc_prep > 10000 ||
|
||||
tx2_reloc_overall <= 0 || tx2_reloc_overall > 20000) {
|
||||
LOG_E(X2AP, "timers in configuration file have wrong values. We must have [0 < t_reloc_prep <= 10000] and [0 < tx2_reloc_overall <= 20000]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).t_reloc_prep = t_reloc_prep;
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).tx2_reloc_overall = tx2_reloc_overall;
|
||||
}
|
||||
// SCTP SETTING
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS;
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS;
|
||||
|
||||
if (EPC_MODE_ENABLED) {
|
||||
sprintf(aprefix,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,k,GNB_CONFIG_STRING_SCTP_CONFIG);
|
||||
config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix);
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr);
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[GNB_SCTP_OUTSTREAMS_IDX].uptr);
|
||||
}
|
||||
|
||||
sprintf(aprefix,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,k,GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
|
||||
// NETWORK_INTERFACES
|
||||
config_get( NETParams,sizeof(NETParams)/sizeof(paramdef_t),aprefix);
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C = (uint32_t)*(NETParams[GNB_PORT_FOR_X2C_IDX].uptr);
|
||||
|
||||
//temp out
|
||||
if ((NETParams[GNB_IPV4_ADDR_FOR_X2C_IDX].strptr == NULL) || (X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C == 0)) {
|
||||
LOG_E(RRC,"Add eNB IPv4 address and/or port for X2C in the CONF file!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cidr = *(NETParams[ENB_IPV4_ADDR_FOR_X2C_IDX].strptr);
|
||||
address = strtok(cidr, "/");
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv6 = 0;
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv4 = 1;
|
||||
strcpy(X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv4_address, address);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -103,6 +103,7 @@ extern void NRRCConfig(void);
|
||||
|
||||
void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc);
|
||||
int RCconfig_NR_S1(MessageDef *msg_p, uint32_t i);
|
||||
int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i);
|
||||
|
||||
#endif /* GNB_CONFIG_H_ */
|
||||
/** @} */
|
||||
|
||||
@@ -113,6 +113,29 @@ typedef enum {
|
||||
#define GNB_CONFIG_STRING_LOCAL_S_PORTD "local_s_portd"
|
||||
#define GNB_CONFIG_STRING_REMOTE_S_PORTD "remote_s_portd"
|
||||
|
||||
typedef struct ccparams_nr_x2 {
|
||||
char *frame_type;
|
||||
int32_t tdd_config;
|
||||
int32_t tdd_config_s;
|
||||
int32_t nr_band;
|
||||
long long int downlink_frequency;
|
||||
int32_t uplink_frequency_offset;
|
||||
int32_t Nid_cell;
|
||||
int32_t N_RB_DL;
|
||||
} ccparams_nr_x2_t;
|
||||
|
||||
|
||||
#define CCPARAMS_NR_X2_DESC(ccparams) { \
|
||||
{ENB_CONFIG_STRING_FRAME_TYPE, NULL, 0, strptr:&ccparams.frame_type, defstrval:"TDD", TYPE_STRING, 0}, \
|
||||
{ENB_CONFIG_STRING_TDD_CONFIG, NULL, 0, iptr:&ccparams.tdd_config, defintval:3, TYPE_UINT, 0}, \
|
||||
{ENB_CONFIG_STRING_TDD_CONFIG_S, NULL, 0, iptr:&ccparams.tdd_config_s, defintval:0, TYPE_UINT, 0}, \
|
||||
{ENB_CONFIG_STRING_EUTRA_BAND, NULL, 0, iptr:&ccparams.nr_band, defintval:78, TYPE_UINT, 0}, \
|
||||
{ENB_CONFIG_STRING_DOWNLINK_FREQUENCY, NULL, 0, i64ptr:(int64_t *)&ccparams.downlink_frequency, defint64val:3600000000, TYPE_UINT64, 0}, \
|
||||
{ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET, NULL, 0, iptr:&ccparams.uplink_frequency_offset, defintval:0, TYPE_INT, 0}, \
|
||||
{ENB_CONFIG_STRING_NID_CELL, NULL, 0, iptr:&ccparams.Nid_cell, defintval:0, TYPE_UINT, 0}, \
|
||||
{ENB_CONFIG_STRING_N_RB_DL, NULL, 0, iptr:&ccparams.N_RB_DL, defintval:106, TYPE_UINT, 0} \
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* cell configuration parameters */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
@@ -262,6 +285,8 @@ typedef enum {
|
||||
#define GNB_INTERFACE_NAME_FOR_S1U_IDX 2
|
||||
#define GNB_IPV4_ADDR_FOR_S1U_IDX 3
|
||||
#define GNB_PORT_FOR_S1U_IDX 4
|
||||
#define GNB_IPV4_ADDR_FOR_X2C_IDX 5
|
||||
#define GNB_PORT_FOR_X2C_IDX 6
|
||||
|
||||
/* S1 interface configuration parameters names */
|
||||
#define GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_S1_MME "GNB_INTERFACE_NAME_FOR_S1_MME"
|
||||
@@ -270,6 +295,10 @@ typedef enum {
|
||||
#define GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_S1U "GNB_IPV4_ADDRESS_FOR_S1U"
|
||||
#define GNB_CONFIG_STRING_GNB_PORT_FOR_S1U "GNB_PORT_FOR_S1U"
|
||||
|
||||
/* X2 interface configuration parameters names */
|
||||
#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"
|
||||
|
||||
/*--------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* S1 interface configuration parameters */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
@@ -279,7 +308,9 @@ typedef enum {
|
||||
{GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_S1_MME, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_S1U, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_S1U, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_PORT_FOR_S1U, NULL, 0, uptr:NULL, defintval:2152L, TYPE_UINT, 0} \
|
||||
{GNB_CONFIG_STRING_GNB_PORT_FOR_S1U, NULL, 0, uptr:NULL, 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} \
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3417,6 +3417,8 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
|
||||
{
|
||||
LTE_DL_DCCH_Message_t dl_dcch_msg;
|
||||
LTE_RAT_Type_t rat=LTE_RAT_Type_eutra;
|
||||
LTE_RAT_Type_t rat_nr=LTE_RAT_Type_nr;
|
||||
LTE_RAT_Type_t rat_eutra_nr=LTE_RAT_Type_eutra_nr;
|
||||
asn_enc_rval_t enc_rval;
|
||||
memset(&dl_dcch_msg,0,sizeof(LTE_DL_DCCH_Message_t));
|
||||
dl_dcch_msg.message.present = LTE_DL_DCCH_MessageType_PR_c1;
|
||||
@@ -3428,6 +3430,45 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
|
||||
dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list.count=0;
|
||||
ASN_SEQUENCE_ADD(&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list,
|
||||
&rat);
|
||||
ASN_SEQUENCE_ADD(&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list,
|
||||
&rat_nr);
|
||||
ASN_SEQUENCE_ADD(&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list,
|
||||
&rat_eutra_nr);
|
||||
|
||||
/* request NR configuration */
|
||||
LTE_UECapabilityEnquiry_r8_IEs_t *r8 = &dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8;
|
||||
LTE_UECapabilityEnquiry_v8a0_IEs_t r8_a0;
|
||||
LTE_UECapabilityEnquiry_v1180_IEs_t r11_80;
|
||||
LTE_UECapabilityEnquiry_v1310_IEs_t r13_10;
|
||||
LTE_UECapabilityEnquiry_v1430_IEs_t r14_30;
|
||||
LTE_UECapabilityEnquiry_v1510_IEs_t r15_10;
|
||||
|
||||
memset(&r8_a0, 0, sizeof(r8_a0));
|
||||
memset(&r11_80, 0, sizeof(r11_80));
|
||||
memset(&r13_10, 0, sizeof(r13_10));
|
||||
memset(&r14_30, 0, sizeof(r14_30));
|
||||
memset(&r15_10, 0, sizeof(r15_10));
|
||||
|
||||
r8->nonCriticalExtension = &r8_a0;
|
||||
r8_a0.nonCriticalExtension = &r11_80;
|
||||
r11_80.nonCriticalExtension = &r13_10;
|
||||
r13_10.nonCriticalExtension = &r14_30;
|
||||
r14_30.nonCriticalExtension = &r15_10;
|
||||
|
||||
OCTET_STRING_t req_freq;
|
||||
//unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x02, 0x68 }; // bands 7 & nr78
|
||||
//unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x08, 0x18 }; // bands 7 & nr260
|
||||
|
||||
//unsigned char req_freq_buf[13] = { 0x00, 0xc0, 0x18, 0x01, 0x01, 0x30, 0x4b, 0x04, 0x0e, 0x08, 0x24, 0x04, 0xd0 };
|
||||
unsigned char req_freq_buf[21] = {
|
||||
0x01, 0x60, 0x18, 0x05, 0x80, 0xc0, 0x04, 0x04, 0xc1, 0x2c, 0x10, 0x08, 0x20, 0x30, 0x40, 0xe0, 0x82, 0x40, 0x28, 0x80, 0x9a
|
||||
};
|
||||
|
||||
req_freq.buf = req_freq_buf;
|
||||
req_freq.size = 5;
|
||||
req_freq.size = 21;
|
||||
|
||||
r15_10.requestedFreqBandsNR_MRDC_r15 = &req_freq;
|
||||
|
||||
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
xer_fprint(stdout, &asn_DEF_LTE_DL_DCCH_Message, (void *)&dl_dcch_msg);
|
||||
|
||||
@@ -92,6 +92,7 @@
|
||||
|
||||
#define PC5_DISCOVERY_PAYLOAD_SIZE 29
|
||||
|
||||
#define DEBUG_SCG_CONFIG 1
|
||||
|
||||
typedef enum {
|
||||
UE_STATE_OFF_NETWORK,
|
||||
@@ -264,7 +265,8 @@ typedef enum UE_STATE_e {
|
||||
RRC_SI_RECEIVED,
|
||||
RRC_CONNECTED,
|
||||
RRC_RECONFIGURED,
|
||||
RRC_HO_EXECUTION
|
||||
RRC_HO_EXECUTION,
|
||||
RRC_NR_NSA,
|
||||
} UE_STATE_t;
|
||||
|
||||
typedef enum HO_STATE_e {
|
||||
@@ -644,6 +646,7 @@ typedef struct eNB_RRC_UE_s {
|
||||
uint32_t ue_rrc_inactivity_timer;
|
||||
uint8_t e_rab_release_command_flag;
|
||||
int8_t reestablishment_xid;
|
||||
int does_nr;
|
||||
} eNB_RRC_UE_t;
|
||||
|
||||
typedef uid_t ue_uid_t;
|
||||
|
||||
+211
-9
@@ -112,6 +112,8 @@ extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t
|
||||
extern int rrc_eNB_process_security(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, security_capabilities_t *security_capabilities_pP);
|
||||
extern void process_eNB_security_key (const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, uint8_t *security_key_pP);
|
||||
extern int derive_keNB_star(const uint8_t *kenb_32, const uint16_t pci, const uint32_t earfcn_dl, const bool is_rel8_only, uint8_t *kenb_star);
|
||||
extern int rrc_eNB_generate_RRCConnectionReconfiguration_endc(protocol_ctxt_t *ctxt, rrc_eNB_ue_context_t *ue_context, unsigned char *buffer, int buffer_size, OCTET_STRING_t *scg_group_config, OCTET_STRING_t *scg_RB_config);
|
||||
extern struct rrc_eNB_ue_context_s * get_first_ue_context(eNB_RRC_INST *rrc_instance_pP);
|
||||
|
||||
pthread_mutex_t rrc_release_freelist;
|
||||
RRC_release_list_t rrc_release_info;
|
||||
@@ -2813,11 +2815,14 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t
|
||||
LTE_MAC_MainConfig_t *mac_MainConfig = NULL;
|
||||
LTE_MeasObjectToAddModList_t *MeasObj_list = NULL;
|
||||
LTE_MeasObjectToAddMod_t *MeasObj = NULL;
|
||||
LTE_MeasObjectToAddMod_t *MeasObj2 = NULL;
|
||||
LTE_ReportConfigToAddModList_t *ReportConfig_list = NULL;
|
||||
LTE_ReportConfigToAddMod_t *ReportConfig_per, *ReportConfig_A1,
|
||||
*ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5;
|
||||
LTE_ReportConfigToAddMod_t *ReportConfig_NR = NULL;
|
||||
LTE_MeasIdToAddModList_t *MeasId_list = NULL;
|
||||
LTE_MeasIdToAddMod_t *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5;
|
||||
LTE_MeasIdToAddMod_t *MeasId6;
|
||||
long *sr_ProhibitTimer_r9 = NULL;
|
||||
long *logicalchannelgroup = NULL;
|
||||
long *logicalchannelgroup_drb = NULL;
|
||||
@@ -3114,6 +3119,16 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t
|
||||
MeasId5->measObjectId = 1;
|
||||
MeasId5->reportConfigId = 6;
|
||||
ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId5);
|
||||
|
||||
if (ue_context_pP->ue_context.does_nr) {
|
||||
MeasId6 = calloc(1, sizeof(LTE_MeasIdToAddMod_t));
|
||||
if (MeasId6 == NULL) exit(1);
|
||||
MeasId6->measId = 7;
|
||||
MeasId6->measObjectId = 2;
|
||||
MeasId6->reportConfigId = 7;
|
||||
ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId6);
|
||||
}
|
||||
|
||||
// LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measIdToAddModList = MeasId_list;
|
||||
// Add one EUTRA Measurement Object
|
||||
MeasObj_list = CALLOC(1, sizeof(*MeasObj_list));
|
||||
@@ -3163,6 +3178,27 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t
|
||||
ASN_SEQUENCE_ADD(&MeasObj_list->list, MeasObj);
|
||||
// LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measObjectToAddModList = MeasObj_list;
|
||||
|
||||
if (ue_context_pP->ue_context.does_nr) {
|
||||
MeasObj2 = calloc(1, sizeof(LTE_MeasObjectToAddMod_t));
|
||||
if (MeasObj2 == NULL) exit(1);
|
||||
MeasObj2->measObjectId = 2;
|
||||
MeasObj2->measObject.present = LTE_MeasObjectToAddMod__measObject_PR_measObjectNR_r15;
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.carrierFreq_r15 = 642256; //634000; //(634000 = 3.51GHz) (640000 = 3.6GHz) (641272 = 3619.08MHz = 3600 + 30/1000*106*12/2) (642256 is for 3.6GHz and absoluteFrequencySSB = 642016)
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.periodicityAndOffset_r15.present = LTE_MTC_SSB_NR_r15__periodicityAndOffset_r15_PR_sf20_r15;
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.periodicityAndOffset_r15.choice.sf20_r15 = 0;
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.ssb_Duration_r15 = LTE_MTC_SSB_NR_r15__ssb_Duration_r15_sf4;
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15 = LTE_RS_ConfigSSB_NR_r15__subcarrierSpacingSSB_r15_kHz30;
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.quantityConfigSet_r15 = 1;
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.ext1 = calloc(1, sizeof(struct LTE_MeasObjectNR_r15__ext1));
|
||||
if (MeasObj2->measObject.choice.measObjectNR_r15.ext1 == NULL) exit(1);
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15 = calloc(1, sizeof(struct LTE_MeasObjectNR_r15__ext1__bandNR_r15));
|
||||
if (MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15 == NULL) exit(1);
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15->present = LTE_MeasObjectNR_r15__ext1__bandNR_r15_PR_setup;
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15->choice.setup = 78;
|
||||
|
||||
ASN_SEQUENCE_ADD(&MeasObj_list->list, MeasObj2);
|
||||
}
|
||||
|
||||
if (!ue_context_pP->ue_context.measurement_info->events) {
|
||||
ue_context_pP->ue_context.measurement_info->events = CALLOC(1,sizeof(*(ue_context_pP->ue_context.measurement_info->events)));
|
||||
}
|
||||
@@ -3175,6 +3211,9 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t
|
||||
ReportConfig_A3 = CALLOC(1, sizeof(*ReportConfig_A3));
|
||||
ReportConfig_A4 = CALLOC(1, sizeof(*ReportConfig_A4));
|
||||
ReportConfig_A5 = CALLOC(1, sizeof(*ReportConfig_A5));
|
||||
if (ue_context_pP->ue_context.does_nr) {
|
||||
ReportConfig_NR = CALLOC(1, sizeof(*ReportConfig_NR));
|
||||
}
|
||||
ReportConfig_per->reportConfigId = 1;
|
||||
ReportConfig_per->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
|
||||
ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.present =
|
||||
@@ -3280,6 +3319,30 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t
|
||||
ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120;
|
||||
ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity;
|
||||
ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A5);
|
||||
|
||||
if (ue_context_pP->ue_context.does_nr) {
|
||||
ReportConfig_NR->reportConfigId = 7;
|
||||
ReportConfig_NR->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigInterRAT;
|
||||
ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.present = LTE_ReportConfigInterRAT__triggerType_PR_event;
|
||||
ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.eventId.present = LTE_ReportConfigInterRAT__triggerType__event__eventId_PR_eventB1_NR_r15;
|
||||
ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.eventId.choice.eventB1_NR_r15.b1_ThresholdNR_r15.present = LTE_ThresholdNR_r15_PR_nr_RSRP_r15;
|
||||
ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.eventId.choice.eventB1_NR_r15.b1_ThresholdNR_r15.choice.nr_RSRP_r15 = 46;
|
||||
ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.eventId.choice.eventB1_NR_r15.reportOnLeave_r15 = FALSE;
|
||||
ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.hysteresis = 2;
|
||||
ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.timeToTrigger = LTE_TimeToTrigger_ms80;
|
||||
ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.maxReportCells = 4;
|
||||
ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.reportInterval = LTE_ReportInterval_ms120;
|
||||
ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.reportAmount = LTE_ReportConfigInterRAT__reportAmount_infinity;
|
||||
ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7 = calloc(1, sizeof(struct LTE_ReportConfigInterRAT__ext7));
|
||||
if (ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7 == NULL) exit(1);
|
||||
ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15 = calloc(1, sizeof(struct LTE_ReportQuantityNR_r15));
|
||||
if (ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15 == NULL) exit(1);
|
||||
ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_rsrp = TRUE;
|
||||
ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_rsrq = TRUE;
|
||||
ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_sinr = TRUE;
|
||||
ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_NR);
|
||||
}
|
||||
|
||||
// LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list;
|
||||
|
||||
/* A3 event update */
|
||||
@@ -4234,6 +4297,10 @@ rrc_eNB_process_MeasurementReport(
|
||||
ctxt_pP->subframe);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
LOG_D(RRC, "NR event frame %d subframe %d\n", ctxt_pP->frame, ctxt_pP->subframe);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_D(RRC,"Other event report frame %d and subframe %d \n", ctxt_pP->frame, ctxt_pP->subframe);
|
||||
break;
|
||||
@@ -4247,6 +4314,22 @@ rrc_eNB_process_MeasurementReport(
|
||||
ue_context_pP->ue_context.measResults->measResultPCell.rsrqResult/2 - 20);
|
||||
}
|
||||
|
||||
/* TODO: improve NR triggering */
|
||||
if (measResults2->measId == 7) {
|
||||
if (ue_context_pP->ue_context.Status != RRC_NR_NSA) {
|
||||
MessageDef *msg;
|
||||
ue_context_pP->ue_context.Status = RRC_NR_NSA;
|
||||
|
||||
msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_ENDC_SGNB_ADDITION_REQ);
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ(msg).rnti = ctxt_pP->rnti;
|
||||
LOG_I(RRC,
|
||||
"[eNB %d] frame %d subframe %d: UE rnti %x switching to NSA mode\n",
|
||||
ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->subframe, ctxt_pP->rnti);
|
||||
itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (measResults2->measResultNeighCells == NULL)
|
||||
return;
|
||||
|
||||
@@ -7658,18 +7741,28 @@ rrc_eNB_decode_dcch(
|
||||
ue_context_p->ue_context.UE_Capability = 0;
|
||||
}
|
||||
|
||||
int eutra_index = -1;
|
||||
|
||||
for (i = 0; i < ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.count; i++) {
|
||||
if (ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[i]->rat_Type == LTE_RAT_Type_eutra) {
|
||||
if (eutra_index != -1) {
|
||||
LOG_E(RRC, "fatal: more than 1 eutra capability\n");
|
||||
exit(1);
|
||||
}
|
||||
eutra_index = i;
|
||||
}
|
||||
/* todo: improve nr dual connectivity capability checking */
|
||||
if (ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[i]->rat_Type == LTE_RAT_Type_eutra_nr)
|
||||
ue_context_p->ue_context.does_nr = 1;
|
||||
}
|
||||
|
||||
dec_rval = uper_decode(NULL,
|
||||
&asn_DEF_LTE_UE_EUTRA_Capability,
|
||||
(void **)&ue_context_p->ue_context.UE_Capability,
|
||||
ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.
|
||||
choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.
|
||||
array[0]->ueCapabilityRAT_Container.buf,
|
||||
ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.
|
||||
choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.
|
||||
array[0]->ueCapabilityRAT_Container.size, 0, 0);
|
||||
ue_context_p->ue_context.UE_Capability_size = ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.
|
||||
choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.
|
||||
array[0]->ueCapabilityRAT_Container.size;
|
||||
ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[eutra_index]->ueCapabilityRAT_Container.buf,
|
||||
ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[eutra_index]->ueCapabilityRAT_Container.size,
|
||||
0, 0);
|
||||
ue_context_p->ue_context.UE_Capability_size = ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[eutra_index]->ueCapabilityRAT_Container.size;
|
||||
|
||||
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
xer_fprint(stdout, &asn_DEF_LTE_UE_EUTRA_Capability, ue_context_p->ue_context.UE_Capability);
|
||||
@@ -8247,6 +8340,100 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_OUT);
|
||||
}
|
||||
|
||||
void rrc_eNB_process_AdditionResponseInformation(const module_id_t enb_mod_idP, x2ap_ENDC_sgnb_addition_req_ACK_t *m) {
|
||||
|
||||
|
||||
NR_CG_Config_t *CG_Config = NULL;
|
||||
|
||||
{
|
||||
int i;
|
||||
printf("%d: ", m->rrc_buffer_size);
|
||||
for (i=0; i<m->rrc_buffer_size; i++) printf("%2.2x", (unsigned char)m->rrc_buffer[i]);
|
||||
printf("\n");
|
||||
|
||||
}
|
||||
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
|
||||
&asn_DEF_NR_CG_Config,
|
||||
(void **)&CG_Config,
|
||||
(uint8_t *)m->rrc_buffer,
|
||||
(int) m->rrc_buffer_size);//m->rrc_buffer_size);
|
||||
|
||||
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||
AssertFatal(1==0,"NR_UL_DCCH_MESSAGE decode error\n");
|
||||
// free the memory
|
||||
SEQUENCE_free( &asn_DEF_NR_CG_Config, CG_Config, 1 );
|
||||
return;
|
||||
}
|
||||
xer_fprint(stdout,&asn_DEF_NR_CG_Config, CG_Config);
|
||||
// recreate enough of X2 EN-DC Container
|
||||
|
||||
AssertFatal(CG_Config->criticalExtensions.choice.c1->present == NR_CG_Config__criticalExtensions__c1_PR_cg_Config,
|
||||
"CG_Config not present\n");
|
||||
|
||||
OCTET_STRING_t *scg_CellGroupConfig = NULL;
|
||||
OCTET_STRING_t *nr1_conf = NULL;
|
||||
|
||||
if(CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig){
|
||||
scg_CellGroupConfig = CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig;
|
||||
#ifdef DEBUG_SCG_CONFIG
|
||||
{
|
||||
int size_s = CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig->size;
|
||||
int i;
|
||||
LOG_I(RRC, "Dumping scg_CellGroupConfig: %d", size_s);
|
||||
for (i=0; i<size_s; i++) printf("%2.2x", (unsigned char)CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig->buf[i]);
|
||||
printf("\n");
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
else{
|
||||
LOG_W(RRC, "SCG Cell group configuration is not present in the Addition Response message \n");
|
||||
return;
|
||||
}
|
||||
if(CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config){
|
||||
nr1_conf = CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config;
|
||||
#ifdef DEBUG_SCG_CONFIG
|
||||
{
|
||||
int size_s = CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config->size;
|
||||
int i;
|
||||
LOG_I(RRC, "Dumping scg_RB_Config: %d", size_s);
|
||||
for (i=0; i<size_s; i++) printf("%2.2x", (unsigned char)CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config->buf[i]);
|
||||
printf("\n");
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else{
|
||||
LOG_W(RRC, "SCG RB configuration is not present in the Addition Response message \n");
|
||||
return;
|
||||
}
|
||||
|
||||
protocol_ctxt_t ctxt;
|
||||
rrc_eNB_ue_context_t *ue_context;
|
||||
unsigned char buffer[8192];
|
||||
int size;
|
||||
|
||||
ue_context = (rrc_eNB_ue_context_t *) get_first_ue_context(RC.rrc[enb_mod_idP]);
|
||||
|
||||
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
|
||||
0,
|
||||
ENB_FLAG_YES,
|
||||
m->rnti,
|
||||
0, 0);
|
||||
|
||||
size = rrc_eNB_generate_RRCConnectionReconfiguration_endc(&ctxt, ue_context, buffer, 8192, scg_CellGroupConfig, nr1_conf);
|
||||
|
||||
rrc_data_req(&ctxt,
|
||||
DCCH,
|
||||
rrc_eNB_mui++,
|
||||
SDU_CONFIRM_NO,
|
||||
size,
|
||||
buffer,
|
||||
PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void *rrc_enb_process_itti_msg(void *notUsed) {
|
||||
MessageDef *msg_p;
|
||||
@@ -8525,6 +8712,12 @@ void *rrc_enb_process_itti_msg(void *notUsed) {
|
||||
break;
|
||||
}
|
||||
|
||||
case X2AP_ENDC_SGNB_ADDITION_REQ_ACK: {
|
||||
rrc_eNB_process_AdditionResponseInformation(ENB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg_p));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* Messages from eNB app */
|
||||
case RRC_CONFIGURATION_REQ:
|
||||
LOG_I(RRC, "[eNB %d] Received %s : %p\n", instance, msg_name_p, &RRC_CONFIGURATION_REQ(msg_p));
|
||||
@@ -8566,11 +8759,20 @@ rrc_enb_task(
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
rrc_enb_init();
|
||||
|
||||
void rrc_endc_hack_init(void);
|
||||
rrc_endc_hack_init();
|
||||
|
||||
itti_mark_task_ready(TASK_RRC_ENB);
|
||||
LOG_I(RRC,"Entering main loop of RRC message task\n");
|
||||
|
||||
while (1) {
|
||||
(void) rrc_enb_process_itti_msg(NULL);
|
||||
{
|
||||
//extern volatile int go_nr;
|
||||
void rrc_go_nr(void);
|
||||
//if (go_nr) rrc_go_nr();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,403 @@
|
||||
/*
|
||||
* 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 "rrc_defs.h"
|
||||
#include "rrc_extern.h"
|
||||
#include "rrc_eNB_UE_context.h"
|
||||
#include "common/ran_context.h"
|
||||
#include "LTE_DL-DCCH-Message.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
extern mui_t rrc_eNB_mui;
|
||||
|
||||
int rrc_eNB_generate_RRCConnectionReconfiguration_endc(protocol_ctxt_t *ctxt,
|
||||
rrc_eNB_ue_context_t *ue_context,
|
||||
unsigned char *buffer,
|
||||
int buffer_size,
|
||||
OCTET_STRING_t *scg_group_config,
|
||||
OCTET_STRING_t *scg_RB_config)
|
||||
{
|
||||
asn_enc_rval_t enc_rval;
|
||||
LTE_DL_DCCH_Message_t dl_dcch_msg;
|
||||
LTE_RRCConnectionReconfiguration_t *r;
|
||||
int trans_id;
|
||||
LTE_RadioResourceConfigDedicated_t rrcd;
|
||||
#if 0
|
||||
LTE_DRB_ToAddModList_t drb_list;
|
||||
struct LTE_DRB_ToAddMod drb;
|
||||
long eps_bearer_id;
|
||||
struct LTE_RLC_Config rlc;
|
||||
long lcid;
|
||||
struct LTE_LogicalChannelConfig lc;
|
||||
#endif
|
||||
LTE_DRB_ToReleaseList_t drb_list;
|
||||
LTE_DRB_Identity_t drb;
|
||||
struct LTE_LogicalChannelConfig__ul_SpecificParameters ul_params;
|
||||
long lcg;
|
||||
struct LTE_RadioResourceConfigDedicated__mac_MainConfig mac;
|
||||
struct LTE_MAC_MainConfig__ext4 mac_ext4;
|
||||
struct LTE_MAC_MainConfig__ext4__dualConnectivityPHR dc_phr;
|
||||
|
||||
memset(&rrcd, 0, sizeof(rrcd));
|
||||
memset(&drb_list, 0, sizeof(drb_list));
|
||||
memset(&drb, 0, sizeof(drb));
|
||||
#if 0
|
||||
memset(&rlc, 0, sizeof(rlc));
|
||||
memset(&lc, 0, sizeof(lc));
|
||||
#endif
|
||||
memset(&ul_params, 0, sizeof(ul_params));
|
||||
memset(&mac, 0, sizeof(mac));
|
||||
memset(&mac_ext4, 0, sizeof(mac_ext4));
|
||||
memset(&dc_phr, 0, sizeof(dc_phr));
|
||||
|
||||
trans_id = rrc_eNB_get_next_transaction_identifier(ctxt->module_id);
|
||||
|
||||
memset(&dl_dcch_msg,0,sizeof(LTE_DL_DCCH_Message_t));
|
||||
|
||||
dl_dcch_msg.message.present = LTE_DL_DCCH_MessageType_PR_c1;
|
||||
dl_dcch_msg.message.choice.c1.present = LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionReconfiguration;
|
||||
|
||||
r = &dl_dcch_msg.message.choice.c1.choice.rrcConnectionReconfiguration;
|
||||
|
||||
r->rrc_TransactionIdentifier = trans_id;
|
||||
r->criticalExtensions.present = LTE_RRCConnectionReconfiguration__criticalExtensions_PR_c1;
|
||||
r->criticalExtensions.choice.c1.present = LTE_RRCConnectionReconfiguration__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r8;
|
||||
r->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated = &rrcd;
|
||||
|
||||
#if 0
|
||||
rrcd.drb_ToAddModList = &drb_list;
|
||||
|
||||
eps_bearer_id = 5;
|
||||
drb.eps_BearerIdentity = &eps_bearer_id;
|
||||
drb.drb_Identity = 5;
|
||||
drb.rlc_Config = &rlc;
|
||||
lcid = 4;
|
||||
drb.logicalChannelIdentity = &lcid;
|
||||
drb.logicalChannelConfig = &lc;
|
||||
|
||||
ASN_SEQUENCE_ADD(&drb_list.list, &drb);
|
||||
|
||||
rlc.present = LTE_RLC_Config_PR_am;
|
||||
rlc.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms50;
|
||||
rlc.choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p16;
|
||||
rlc.choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity;
|
||||
rlc.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8;
|
||||
rlc.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35;
|
||||
rlc.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms25;
|
||||
|
||||
lc.ul_SpecificParameters = &ul_params;
|
||||
#endif
|
||||
|
||||
/* release drb 1 */
|
||||
drb = 1;
|
||||
ASN_SEQUENCE_ADD(&drb_list.list, &drb);
|
||||
rrcd.drb_ToReleaseList = &drb_list;
|
||||
|
||||
ul_params.priority = 12;
|
||||
ul_params.prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8;
|
||||
ul_params.bucketSizeDuration = LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms300;
|
||||
lcg = 3;
|
||||
ul_params.logicalChannelGroup = &lcg;
|
||||
|
||||
rrcd.mac_MainConfig = &mac;
|
||||
|
||||
mac.present = LTE_RadioResourceConfigDedicated__mac_MainConfig_PR_explicitValue;
|
||||
mac.choice.explicitValue.timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_sf10240;
|
||||
mac.choice.explicitValue.ext4 = &mac_ext4;
|
||||
|
||||
mac_ext4.dualConnectivityPHR = &dc_phr;
|
||||
|
||||
dc_phr.present = LTE_MAC_MainConfig__ext4__dualConnectivityPHR_PR_setup;
|
||||
dc_phr.choice.setup.phr_ModeOtherCG_r12 = LTE_MAC_MainConfig__ext4__dualConnectivityPHR__setup__phr_ModeOtherCG_r12_virtual;
|
||||
|
||||
/* NR config */
|
||||
struct LTE_RRCConnectionReconfiguration_v890_IEs cr_890;
|
||||
struct LTE_RRCConnectionReconfiguration_v920_IEs cr_920;
|
||||
struct LTE_RRCConnectionReconfiguration_v1020_IEs cr_1020;
|
||||
struct LTE_RRCConnectionReconfiguration_v1130_IEs cr_1130;
|
||||
struct LTE_RRCConnectionReconfiguration_v1250_IEs cr_1250;
|
||||
struct LTE_RRCConnectionReconfiguration_v1310_IEs cr_1310;
|
||||
struct LTE_RRCConnectionReconfiguration_v1430_IEs cr_1430;
|
||||
struct LTE_RRCConnectionReconfiguration_v1510_IEs cr_1510;
|
||||
struct LTE_RRCConnectionReconfiguration_v1510_IEs__nr_Config_r15 nr;
|
||||
|
||||
memset(&cr_890, 0, sizeof(cr_890));
|
||||
memset(&cr_920, 0, sizeof(cr_920));
|
||||
memset(&cr_1020, 0, sizeof(cr_1020));
|
||||
memset(&cr_1130, 0, sizeof(cr_1130));
|
||||
memset(&cr_1250, 0, sizeof(cr_1250));
|
||||
memset(&cr_1310, 0, sizeof(cr_1310));
|
||||
memset(&cr_1430, 0, sizeof(cr_1430));
|
||||
memset(&cr_1510, 0, sizeof(cr_1510));
|
||||
memset(&nr, 0, sizeof(nr));
|
||||
|
||||
r->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension = &cr_890;
|
||||
cr_890.nonCriticalExtension = &cr_920;
|
||||
cr_920.nonCriticalExtension = &cr_1020;
|
||||
cr_1020.nonCriticalExtension = &cr_1130;
|
||||
cr_1130.nonCriticalExtension = &cr_1250;
|
||||
cr_1250.nonCriticalExtension = &cr_1310;
|
||||
cr_1310.nonCriticalExtension = &cr_1430;
|
||||
cr_1430.nonCriticalExtension = &cr_1510;
|
||||
|
||||
cr_1510.nr_Config_r15 = &nr;
|
||||
nr.present = LTE_RRCConnectionReconfiguration_v1510_IEs__nr_Config_r15_PR_setup;
|
||||
nr.choice.setup.endc_ReleaseAndAdd_r15 = 0; /* FALSE */
|
||||
|
||||
OCTET_STRING_t dummy_scg_conf;
|
||||
unsigned char scg_conf_buf[4] = { 0, 0, 0, 0 };
|
||||
if (scg_group_config!=NULL)
|
||||
nr.choice.setup.nr_SecondaryCellGroupConfig_r15 = scg_group_config; //&scg_conf;
|
||||
else{
|
||||
nr.choice.setup.nr_SecondaryCellGroupConfig_r15 = &dummy_scg_conf;
|
||||
dummy_scg_conf.buf = scg_conf_buf;
|
||||
dummy_scg_conf.size = 4;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SCG_CONFIG
|
||||
{
|
||||
int size_s = nr.choice.setup.nr_SecondaryCellGroupConfig_r15->size;
|
||||
int i;
|
||||
LOG_I(RRC, "Dumping nr_SecondaryCellGroupConfig: %d", size_s);
|
||||
for (i=0; i<size_s; i++) printf("%2.2x", (unsigned char)nr.choice.setup.nr_SecondaryCellGroupConfig_r15->buf[i]);
|
||||
printf("\n");
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
long sk_counter = 0;
|
||||
cr_1510.sk_Counter_r15 = &sk_counter;
|
||||
|
||||
OCTET_STRING_t dummy_nr1_conf;
|
||||
unsigned char nr1_buf[4] = { 0, 0, 0, 0 };
|
||||
|
||||
if(scg_RB_config!=NULL)
|
||||
cr_1510.nr_RadioBearerConfig1_r15 = scg_RB_config;
|
||||
else{
|
||||
cr_1510.nr_RadioBearerConfig1_r15 = &dummy_nr1_conf;
|
||||
dummy_nr1_conf.buf = nr1_buf;
|
||||
dummy_nr1_conf.size = 4;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SCG_CONFIG
|
||||
{
|
||||
int size_s = cr_1510.nr_RadioBearerConfig1_r15->size;
|
||||
int i;
|
||||
LOG_I(RRC, "Dumping nr_RadioBearerConfig1: %d", size_s);
|
||||
for (i=0; i<size_s; i++) printf("%2.2x", (unsigned char)cr_1510.nr_RadioBearerConfig1_r15->buf[i]);
|
||||
printf("\n");
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
OCTET_STRING_t nr2_conf;
|
||||
unsigned char nr2_buf[4] = { 0, 0, 0, 0 };
|
||||
cr_1510.nr_RadioBearerConfig2_r15 = &nr2_conf;
|
||||
nr2_conf.buf = nr2_buf;
|
||||
nr2_conf.size = 4;
|
||||
#endif
|
||||
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message,
|
||||
NULL,
|
||||
(void *)&dl_dcch_msg,
|
||||
buffer,
|
||||
buffer_size);
|
||||
|
||||
{
|
||||
int len = (enc_rval.encoded + 7) / 8;
|
||||
int i;
|
||||
printf("len = %d\n", len);
|
||||
for (i = 0; i < len; i++) printf(" %2.2x", buffer[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return (enc_rval.encoded + 7) / 8;
|
||||
}
|
||||
|
||||
volatile int go_nr;
|
||||
|
||||
struct rrc_eNB_ue_context_s *
|
||||
get_first_ue_context(eNB_RRC_INST *rrc_instance_pP)
|
||||
{
|
||||
struct rrc_eNB_ue_context_s *ue_context_p = NULL;
|
||||
RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(rrc_instance_pP->rrc_ue_head)) {
|
||||
return ue_context_p;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rrc_go_nr(void)
|
||||
{
|
||||
protocol_ctxt_t ctxt;
|
||||
rrc_eNB_ue_context_t *ue_context;
|
||||
unsigned char buffer[8192];
|
||||
int size;
|
||||
|
||||
go_nr = 0;
|
||||
|
||||
ue_context = get_first_ue_context(RC.rrc[0]);
|
||||
|
||||
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
|
||||
0,
|
||||
ENB_FLAG_YES,
|
||||
ue_context->ue_context.rnti,
|
||||
0, 0);
|
||||
|
||||
size = rrc_eNB_generate_RRCConnectionReconfiguration_endc(&ctxt, ue_context, buffer, 8192, NULL, NULL);
|
||||
|
||||
rrc_data_req(&ctxt,
|
||||
DCCH,
|
||||
rrc_eNB_mui++,
|
||||
SDU_CONFIRM_NO,
|
||||
size,
|
||||
buffer,
|
||||
PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
}
|
||||
|
||||
static void new_thread(void *(*f)(void *), void *data) {
|
||||
pthread_t t;
|
||||
pthread_attr_t att;
|
||||
|
||||
if (pthread_attr_init(&att)) {
|
||||
fprintf(stderr, "pthread_attr_init err\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) {
|
||||
fprintf(stderr, "pthread_attr_setdetachstate err\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (pthread_attr_setstacksize(&att, 10000000)) {
|
||||
fprintf(stderr, "pthread_attr_setstacksize err\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (pthread_create(&t, &att, f, data)) {
|
||||
fprintf(stderr, "pthread_create err\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (pthread_attr_destroy(&att)) {
|
||||
fprintf(stderr, "pthread_attr_destroy err\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static int create_listen_socket(char *addr, int port) {
|
||||
struct sockaddr_in a;
|
||||
int s;
|
||||
int v;
|
||||
s = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
if (s == -1) {
|
||||
perror("socket");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
v = 1;
|
||||
|
||||
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(int))) {
|
||||
perror("setsockopt");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
a.sin_family = AF_INET;
|
||||
a.sin_port = htons(port);
|
||||
a.sin_addr.s_addr = inet_addr(addr);
|
||||
|
||||
if (bind(s, (struct sockaddr *)&a, sizeof(a))) {
|
||||
perror("bind");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (listen(s, 5)) {
|
||||
perror("listen");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static int socket_accept(int s) {
|
||||
struct sockaddr_in a;
|
||||
socklen_t alen;
|
||||
alen = sizeof(a);
|
||||
return accept(s, (struct sockaddr *)&a, &alen);
|
||||
}
|
||||
|
||||
static int fullread(int fd, void *_buf, int count) {
|
||||
char *buf = _buf;
|
||||
int ret = 0;
|
||||
int l;
|
||||
|
||||
while (count) {
|
||||
l = read(fd, buf, count);
|
||||
|
||||
if (l <= 0) return -1;
|
||||
|
||||
count -= l;
|
||||
buf += l;
|
||||
ret += l;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *nr_hack(void *_)
|
||||
{
|
||||
int s = create_listen_socket("0.0.0.0", 9001);
|
||||
int t;
|
||||
|
||||
over:
|
||||
t = socket_accept(s);
|
||||
|
||||
while (1) {
|
||||
char c;
|
||||
|
||||
if (fullread(t, &c, 1) != 1) {
|
||||
close(t);
|
||||
goto over;
|
||||
}
|
||||
|
||||
if (c != '\n') continue;
|
||||
|
||||
printf("setting go_nr to 1\n");
|
||||
go_nr = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rrc_endc_hack_init(void)
|
||||
{
|
||||
new_thread(nr_hack, NULL);
|
||||
}
|
||||
@@ -204,7 +204,7 @@ static void init_NR_SI(gNB_RRC_INST *rrc) {
|
||||
);
|
||||
|
||||
|
||||
if (phy_test > 0) {
|
||||
/*if (phy_test > 0) {
|
||||
// This is for phytest only, emulate first X2 message if uecap.raw file is present
|
||||
FILE *fd;
|
||||
|
||||
@@ -253,7 +253,7 @@ static void init_NR_SI(gNB_RRC_INST *rrc) {
|
||||
LOG_I(NR_RRC,"Adding new user (%p)\n",ue_context_p);
|
||||
rrc_add_nsa_user(rrc,ue_context_p);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
@@ -300,6 +300,52 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu
|
||||
}//END openair_rrc_gNB_configuration
|
||||
|
||||
|
||||
void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x2ap_ENDC_sgnb_addition_req_t *m) {
|
||||
|
||||
|
||||
LTE_UL_DCCH_Message_t *LTE_UL_DCCH_Message = NULL;
|
||||
|
||||
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
|
||||
&asn_DEF_LTE_UL_DCCH_Message,
|
||||
(void **)<E_UL_DCCH_Message,
|
||||
(uint8_t *)m->rrc_buffer,
|
||||
(int) m->rrc_buffer_size);//m->rrc_buffer_size);
|
||||
|
||||
/* asn_dec_rval_t dec_rval = uper_decode( NULL,
|
||||
&asn_DEF_LTE_UL_DCCH_Message,
|
||||
(void **)<E_UL_DCCH_Message,
|
||||
(uint8_t *)m->rrc_buffer,
|
||||
(int) m->rrc_buffer_size, 0, 0);//m->rrc_buffer_size);
|
||||
*/
|
||||
gNB_RRC_INST *rrc=RC.nrrrc[gnb_mod_idP];
|
||||
|
||||
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||
AssertFatal(1==0,"NR_UL_DCCH_MESSAGE decode error\n");
|
||||
// free the memory
|
||||
SEQUENCE_free( &asn_DEF_LTE_UL_DCCH_Message, LTE_UL_DCCH_Message, 1 );
|
||||
return;
|
||||
}
|
||||
xer_fprint(stdout,&asn_DEF_LTE_UL_DCCH_Message, LTE_UL_DCCH_Message);
|
||||
// recreate enough of X2 EN-DC Container
|
||||
AssertFatal(LTE_UL_DCCH_Message->message.choice.c1.present == LTE_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation,
|
||||
"ueCapabilityInformation not present\n");
|
||||
NR_CG_ConfigInfo_t *CG_ConfigInfo = calloc(1,sizeof(*CG_ConfigInfo));
|
||||
CG_ConfigInfo->criticalExtensions.present = NR_CG_ConfigInfo__criticalExtensions_PR_c1;
|
||||
CG_ConfigInfo->criticalExtensions.choice.c1 = calloc(1,sizeof(*CG_ConfigInfo->criticalExtensions.choice.c1));
|
||||
CG_ConfigInfo->criticalExtensions.choice.c1->present = NR_CG_ConfigInfo__criticalExtensions__c1_PR_cg_ConfigInfo;
|
||||
CG_ConfigInfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo = calloc(1,sizeof(*CG_ConfigInfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo));
|
||||
NR_CG_ConfigInfo_IEs_t *cg_ConfigInfo = CG_ConfigInfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo;
|
||||
cg_ConfigInfo->ue_CapabilityInfo = calloc(1,sizeof(*cg_ConfigInfo->ue_CapabilityInfo));
|
||||
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UE_CapabilityRAT_ContainerList,NULL,(void*)<E_UL_DCCH_Message->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList,m->rrc_buffer,m->rrc_buffer_size);
|
||||
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
OCTET_STRING_fromBuf(cg_ConfigInfo->ue_CapabilityInfo,
|
||||
(const char *)m->rrc_buffer,
|
||||
(enc_rval.encoded+7)>>3);
|
||||
parse_CG_ConfigInfo(rrc,CG_ConfigInfo);
|
||||
|
||||
}
|
||||
|
||||
///---------------------------------------------------------------------------------------------------------------///
|
||||
///---------------------------------------------------------------------------------------------------------------///
|
||||
|
||||
@@ -396,6 +442,17 @@ void *rrc_gnb_task(void *args_p) {
|
||||
openair_rrc_gNB_configuration(GNB_INSTANCE_TO_MODULE_ID(instance), &NRRRC_CONFIGURATION_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");
|
||||
rrc_gNB_process_AdditionRequestInformation(GNB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_SGNB_ADDITION_REQ(msg_p));
|
||||
break;
|
||||
|
||||
case X2AP_ENDC_SGNB_RECONF_COMPLETE:
|
||||
LOG_I(NR_RRC, "Handling of reconfiguration complete message at RRC gNB is pending \n");
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
LOG_E(NR_RRC, "[gNB %d] Received unexpected message %s\n", instance, msg_name_p);
|
||||
break;
|
||||
|
||||
@@ -85,13 +85,15 @@ int generate_CG_Config(gNB_RRC_INST *rrc,
|
||||
cg_Config->criticalExtensions.choice.c1->present = NR_CG_Config__criticalExtensions__c1_PR_cg_Config;
|
||||
cg_Config->criticalExtensions.choice.c1->choice.cg_Config = calloc(1,sizeof(NR_CG_Config_IEs_t));
|
||||
char buffer[1024];
|
||||
int total_size;
|
||||
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_RRCReconfiguration, NULL, (void *)reconfig, buffer, 1024);
|
||||
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
cg_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig = calloc(1,sizeof(OCTET_STRING_t));
|
||||
OCTET_STRING_fromBuf(cg_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig,
|
||||
(const char *)buffer,
|
||||
(enc_rval.encoded+7)>>3);
|
||||
(enc_rval.encoded+7)>>3);
|
||||
total_size = (enc_rval.encoded+7)>>3;
|
||||
|
||||
LOG_I(RRC,"Dumping NR_RRCReconfiguration message (%jd bytes)\n",(enc_rval.encoded+7)>>3);
|
||||
for (int i=0;i<(enc_rval.encoded+7)>>3;i++) {
|
||||
@@ -117,8 +119,9 @@ int generate_CG_Config(gNB_RRC_INST *rrc,
|
||||
fd = fopen("rbconfig.raw","w");
|
||||
fwrite((void*)buffer,1,(size_t)((enc_rval.encoded+7)>>3),fd);
|
||||
fclose(fd);
|
||||
total_size = total_size + ((enc_rval.encoded+7)>>3);
|
||||
|
||||
return(0);
|
||||
return(total_size);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -103,6 +103,9 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
|
||||
rrc_gNB_carrier_data_t *carrier=&rrc->carrier;
|
||||
|
||||
MessageDef *msg;
|
||||
msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_ENDC_SGNB_ADDITION_REQ_ACK);
|
||||
|
||||
// NR RRCReconfiguration
|
||||
|
||||
AssertFatal(rrc->Nb_ue < MAX_NR_RRC_UE_CONTEXTS,"cannot add another UE\n");
|
||||
@@ -127,8 +130,19 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
ue_context_p->ue_id_rnti = ue_context_p->ue_context.secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity;
|
||||
NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config));
|
||||
memset((void*)CG_Config,0,sizeof(*CG_Config));
|
||||
generate_CG_Config(rrc,CG_Config,ue_context_p->ue_context.reconfig,ue_context_p->ue_context.rb_config);
|
||||
int CG_Config_size = generate_CG_Config(rrc,CG_Config,ue_context_p->ue_context.reconfig,ue_context_p->ue_context.rb_config);
|
||||
|
||||
//X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = CG_Config_size; //Need to verify correct value for the buffer_size
|
||||
// Send to X2 entity to transport to MeNB
|
||||
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_Config,
|
||||
NULL,
|
||||
(void *)CG_Config,
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer,
|
||||
1024);
|
||||
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = (enc_rval.encoded+7)>>3;
|
||||
|
||||
itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(0), msg); //Check right id instead of hardcoding
|
||||
|
||||
rrc->Nb_ue++;
|
||||
// configure MAC and RLC
|
||||
|
||||
@@ -64,7 +64,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
RLC_BearerConfig->servedRadioBearer = calloc(1,sizeof(*RLC_BearerConfig->servedRadioBearer));
|
||||
RLC_BearerConfig->servedRadioBearer->present = NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity;
|
||||
|
||||
RLC_BearerConfig->servedRadioBearer->choice.drb_Identity=5;
|
||||
RLC_BearerConfig->servedRadioBearer->choice.drb_Identity=1;
|
||||
RLC_BearerConfig->reestablishRLC=calloc(1,sizeof(*RLC_BearerConfig->reestablishRLC));
|
||||
*RLC_BearerConfig->reestablishRLC=NR_RLC_BearerConfig__reestablishRLC_true;
|
||||
RLC_BearerConfig->rlc_Config=calloc(1,sizeof(*RLC_BearerConfig->rlc_Config));
|
||||
@@ -106,7 +106,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig = NULL;
|
||||
secondaryCellGroup->mac_CellGroupConfig->bsr_Config=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->bsr_Config));
|
||||
secondaryCellGroup->mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf80;
|
||||
secondaryCellGroup->mac_CellGroupConfig->bsr_Config->retxBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf320;
|
||||
secondaryCellGroup->mac_CellGroupConfig->bsr_Config->retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf320;
|
||||
secondaryCellGroup->mac_CellGroupConfig->tag_Config=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->tag_Config));
|
||||
secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToReleaseList = NULL;
|
||||
secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToAddModList = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToAddModList));
|
||||
@@ -375,7 +375,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->sp_ZP_CSI_RS_ResourceSetsToAddModList=NULL;
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->sp_ZP_CSI_RS_ResourceSetsToReleaseList=NULL;
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->p_ZP_CSI_RS_ResourceSet=NULL;
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->sps_Config = NULL;
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->sps_Config = NULL; //calloc(1,sizeof(struct NR_SetupRelease_SPS_Config));
|
||||
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig));
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig->present = NR_SetupRelease_RadioLinkMonitoringConfig_PR_setup;
|
||||
@@ -794,7 +794,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->sp_ZP_CSI_RS_ResourceSetsToAddModList=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->sp_ZP_CSI_RS_ResourceSetsToReleaseList=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->p_ZP_CSI_RS_ResourceSet=NULL;
|
||||
bwp->bwp_Dedicated->sps_Config = NULL;
|
||||
bwp->bwp_Dedicated->sps_Config = NULL; //calloc(1,sizeof(struct NR_SetupRelease_SPS_Config));
|
||||
|
||||
bwp->bwp_Dedicated->radioLinkMonitoringConfig = calloc(1,sizeof(*bwp->bwp_Dedicated->radioLinkMonitoringConfig));
|
||||
bwp->bwp_Dedicated->radioLinkMonitoringConfig->present = NR_SetupRelease_RadioLinkMonitoringConfig_PR_setup;
|
||||
@@ -2044,7 +2044,7 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) {
|
||||
drb_ToAddMod->cnAssociation = calloc(1,sizeof(*drb_ToAddMod->cnAssociation));
|
||||
drb_ToAddMod->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity;
|
||||
drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity=5;
|
||||
drb_ToAddMod->drb_Identity = 4;
|
||||
drb_ToAddMod->drb_Identity = 1;
|
||||
drb_ToAddMod->reestablishPDCP = NULL;
|
||||
drb_ToAddMod->recoverPDCP = NULL;
|
||||
drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config));
|
||||
@@ -2073,7 +2073,7 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) {
|
||||
|
||||
rbconfig->securityConfig = calloc(1,sizeof(*rbconfig->securityConfig));
|
||||
rbconfig->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(*rbconfig->securityConfig->securityAlgorithmConfig));
|
||||
rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea2;
|
||||
rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0;
|
||||
rbconfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm=NULL;
|
||||
rbconfig->securityConfig->keyToUse = calloc(1,sizeof(*rbconfig->securityConfig->keyToUse));
|
||||
*rbconfig->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master;
|
||||
|
||||
+97
-10
@@ -101,7 +101,6 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
x2ap_eNB_data_t *x2ap_enb_data_p;
|
||||
DevAssert(sctp_new_association_resp != NULL);
|
||||
printf("x2ap_eNB_handle_sctp_association_resp at 1\n");
|
||||
dump_trees();
|
||||
instance_p = x2ap_eNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
@@ -129,7 +128,6 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
|
||||
x2ap_enb_data_p = x2ap_get_eNB(instance_p, -1,
|
||||
sctp_new_association_resp->ulp_cnx_id);
|
||||
DevAssert(x2ap_enb_data_p != NULL);
|
||||
printf("x2ap_eNB_handle_sctp_association_resp at 2\n");
|
||||
dump_trees();
|
||||
|
||||
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
|
||||
@@ -142,17 +140,17 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
|
||||
return;
|
||||
}
|
||||
|
||||
printf("x2ap_eNB_handle_sctp_association_resp at 3\n");
|
||||
dump_trees();
|
||||
/* Update parameters */
|
||||
x2ap_enb_data_p->assoc_id = sctp_new_association_resp->assoc_id;
|
||||
x2ap_enb_data_p->in_streams = sctp_new_association_resp->in_streams;
|
||||
x2ap_enb_data_p->out_streams = sctp_new_association_resp->out_streams;
|
||||
printf("x2ap_eNB_handle_sctp_association_resp at 4\n");
|
||||
dump_trees();
|
||||
/* Prepare new x2 Setup Request */
|
||||
x2ap_eNB_generate_x2_setup_request(instance_p, x2ap_enb_data_p);
|
||||
//x2ap_eNB_generate_ENDC_x2_setup_request(instance_p, x2ap_enb_data_p);
|
||||
if(instance_p->cell_type == CELL_MACRO_GNB)
|
||||
x2ap_gNB_generate_ENDC_x2_setup_request(instance_p, x2ap_enb_data_p);
|
||||
else
|
||||
x2ap_eNB_generate_x2_setup_request(instance_p, x2ap_enb_data_p);
|
||||
}
|
||||
|
||||
static
|
||||
@@ -448,6 +446,78 @@ void x2ap_eNB_handle_handover_req_ack(instance_t instance,
|
||||
x2ap_eNB_generate_x2_handover_request_ack(instance_p, target, x2ap_handover_req_ack);
|
||||
}
|
||||
|
||||
static
|
||||
void x2ap_eNB_handle_sgNB_add_req(instance_t instance,
|
||||
x2ap_ENDC_sgnb_addition_req_t *x2ap_ENDC_sgnb_addition_req)
|
||||
{
|
||||
x2ap_id_manager *id_manager;
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
x2ap_eNB_data_t *x2ap_eNB_data;
|
||||
int ue_id;
|
||||
|
||||
/* TODO: remove hardcoded value */
|
||||
x2ap_eNB_data = x2ap_is_eNB_id_in_list(3584);
|
||||
DevAssert(x2ap_eNB_data != NULL);
|
||||
|
||||
instance_p = x2ap_eNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
|
||||
/* allocate x2ap ID */
|
||||
id_manager = &instance_p->id_manager;
|
||||
ue_id = x2ap_allocate_new_id(id_manager);
|
||||
if (ue_id == -1) {
|
||||
X2AP_ERROR("could not allocate a new X2AP UE ID\n");
|
||||
/* TODO: cancel NSA: send (to be defined) message to RRC */
|
||||
exit(1);
|
||||
}
|
||||
/* id_source is ue_id, id_target is unknown yet */
|
||||
x2ap_set_ids(id_manager, ue_id, x2ap_ENDC_sgnb_addition_req->rnti, ue_id, -1);
|
||||
x2ap_id_set_state(id_manager, ue_id, X2ID_STATE_NSA_PREPARE);
|
||||
|
||||
x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(instance_p, x2ap_eNB_data, ue_id);
|
||||
}
|
||||
|
||||
static
|
||||
void x2ap_gNB_trigger_sgNB_add_req_ack(instance_t instance,
|
||||
x2ap_ENDC_sgnb_addition_req_ACK_t *x2ap_ENDC_sgnb_addition_req_ACK)
|
||||
{
|
||||
/* TODO: remove this hack (the goal is to find the correct
|
||||
* eNodeB structure for the other end) - we need a proper way for RRC
|
||||
* and X2AP to identify eNodeBs
|
||||
* RRC knows about mod_id and X2AP knows about eNB_id (eNB_ID in
|
||||
* the configuration file)
|
||||
* as far as I understand.. CROUX
|
||||
*/
|
||||
|
||||
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
x2ap_eNB_data_t *target;
|
||||
/*int source_assoc_id = x2ap_ENDC_sgnb_addition_req_ACK->source_assoc_id;
|
||||
int ue_id;
|
||||
int id_source;
|
||||
int id_target;*/
|
||||
|
||||
instance_p = x2ap_eNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
|
||||
/*target = x2ap_get_eNB(NULL, source_assoc_id, 0);
|
||||
DevAssert(target != NULL);*/
|
||||
|
||||
// rnti is a new information, save it
|
||||
|
||||
/*ue_id = x2ap_handover_req_ack->x2_id_target;
|
||||
id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
|
||||
id_target = ue_id;
|
||||
x2ap_set_ids(&instance_p->id_manager, ue_id, x2ap_handover_req_ack->rnti, id_source, id_target);*/
|
||||
|
||||
|
||||
//target = x2ap_get_eNB(NULL, 17, 0);
|
||||
target = x2ap_is_eNB_id_in_list (3585); //Currently hardcoded. Need to extract it differently
|
||||
DevAssert(target != NULL);
|
||||
x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK(instance_p, target, x2ap_ENDC_sgnb_addition_req_ACK, 0);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void x2ap_eNB_ue_context_release(instance_t instance,
|
||||
x2ap_ue_context_release_t *x2ap_ue_context_release)
|
||||
@@ -513,6 +583,17 @@ void *x2ap_task(void *arg) {
|
||||
&X2AP_UE_CONTEXT_RELEASE(received_msg));
|
||||
break;
|
||||
|
||||
case X2AP_ENDC_SGNB_ADDITION_REQ:
|
||||
x2ap_eNB_handle_sgNB_add_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
&X2AP_ENDC_SGNB_ADDITION_REQ(received_msg));
|
||||
break;
|
||||
|
||||
case X2AP_ENDC_SGNB_ADDITION_REQ_ACK:
|
||||
x2ap_gNB_trigger_sgNB_add_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
&X2AP_ENDC_SGNB_ADDITION_REQ_ACK(received_msg));
|
||||
LOG_I(X2AP, "Received elements for X2AP_ENDC_SGNB_ADDITION_REQ_ACK \n");
|
||||
break;
|
||||
|
||||
case SCTP_INIT_MSG_MULTI_CNF:
|
||||
x2ap_eNB_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_init_msg_multi_cnf);
|
||||
@@ -556,7 +637,6 @@ int is_x2ap_enabled(void)
|
||||
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;
|
||||
@@ -569,13 +649,20 @@ int is_x2ap_enabled(void)
|
||||
|
||||
/* TODO: do it per module - we check only first eNB */
|
||||
config_get(p, sizeof(p)/sizeof(paramdef_t), "eNBs.[0]");
|
||||
if (enable_x2 != NULL && strcmp(enable_x2, "yes") == 0)
|
||||
enabled = 1;
|
||||
if (enable_x2 != NULL && strcmp(enable_x2, "yes") == 0){
|
||||
enabled = 1;
|
||||
}
|
||||
|
||||
/*Consider also the case of enabling X2AP for a gNB by parsing a gNB configuration file*/
|
||||
|
||||
config_get(p, sizeof(p)/sizeof(paramdef_t), "gNBs.[0]");
|
||||
if (enable_x2 != NULL && strcmp(enable_x2, "yes") == 0){
|
||||
enabled = 1;
|
||||
}
|
||||
|
||||
config_loaded = 1;
|
||||
|
||||
if (pthread_mutex_unlock(&mutex)) goto mutex_error;
|
||||
|
||||
return enabled;
|
||||
|
||||
mutex_error:
|
||||
|
||||
@@ -60,8 +60,14 @@ static int x2ap_eNB_decode_initiating_message(X2AP_X2AP_PDU_t *pdu)
|
||||
break;
|
||||
|
||||
case X2AP_ProcedureCode_id_endcX2Setup:
|
||||
X2AP_INFO("X2AP_ProcedureCode_id_endcX2Setup message!\n");
|
||||
break;
|
||||
X2AP_INFO("X2AP_ProcedureCode_id_endcX2Setup message!\n");
|
||||
break;
|
||||
case X2AP_ProcedureCode_id_sgNBAdditionPreparation:
|
||||
X2AP_INFO("X2AP_ProcedureCode_id_sgNBAdditionPreparation message!\n");
|
||||
break;
|
||||
case X2AP_ProcedureCode_id_sgNBReconfigurationCompletion:
|
||||
X2AP_INFO("X2AP_ProcedureCode_id_sgNBReconfigurationCompletion message!\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
X2AP_ERROR("Unknown procedure ID (%d) for initiating message\n",
|
||||
@@ -93,6 +99,10 @@ static int x2ap_eNB_decode_successful_outcome(X2AP_X2AP_PDU_t *pdu)
|
||||
X2AP_INFO("x2ap_eNB_decode_successfuloutcome_message!\n");
|
||||
break;
|
||||
|
||||
case X2AP_ProcedureCode_id_sgNBAdditionPreparation:
|
||||
X2AP_INFO("x2ap_eNB_decode_successfuloutcome_message!\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
X2AP_ERROR("Unknown procedure ID (%d) for successfull outcome message\n",
|
||||
(int)pdu->choice.successfulOutcome.procedureCode);
|
||||
@@ -134,9 +144,9 @@ int x2ap_eNB_decode_pdu(X2AP_X2AP_PDU_t *pdu, const uint8_t *const buffer, uint3
|
||||
length,
|
||||
0,
|
||||
0);
|
||||
if (asn1_xer_print) {
|
||||
//if (asn1_xer_print) {
|
||||
xer_fprint(stdout, &asn_DEF_X2AP_X2AP_PDU, pdu);
|
||||
}
|
||||
//}
|
||||
|
||||
if (dec_ret.code != RC_OK) {
|
||||
X2AP_ERROR("Failed to decode pdu\n");
|
||||
|
||||
@@ -44,9 +44,9 @@ int x2ap_eNB_encode_pdu(X2AP_X2AP_PDU_t *pdu, uint8_t **buffer, uint32_t *len)
|
||||
DevAssert(buffer != NULL);
|
||||
DevAssert(len != NULL);
|
||||
|
||||
if (asn1_xer_print) {
|
||||
//if (asn1_xer_print) {
|
||||
xer_fprint(stdout, &asn_DEF_X2AP_X2AP_PDU, (void *)pdu);
|
||||
}
|
||||
//}
|
||||
|
||||
encoded = aper_encode_to_new_buffer(&asn_DEF_X2AP_X2AP_PDU, 0, pdu, (void **)buffer);
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "x2ap_ids.h"
|
||||
|
||||
#include "x2ap_eNB_itti_messaging.h"
|
||||
#include "X2AP_SupportedSULFreqBandItem.h"
|
||||
|
||||
#include "msc.h"
|
||||
#include "assertions.h"
|
||||
@@ -1097,7 +1098,6 @@ int x2ap_eNB_generate_senb_addition_request (x2ap_eNB_instance_t *instance_p, x2
|
||||
return ret;
|
||||
}
|
||||
|
||||
//Panos:
|
||||
int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
|
||||
x2ap_senb_addition_req_ack_t *x2ap_addition_req_ack)
|
||||
{
|
||||
@@ -1118,8 +1118,6 @@ int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p
|
||||
DevAssert(instance_p != NULL);
|
||||
DevAssert(x2ap_eNB_data_p != NULL);
|
||||
|
||||
//Panos: The fact that we have separate IDs here is because the ID for a specific UE might be different
|
||||
//between the 2 eNBs?
|
||||
//ue_id = x2ap_addition_req_ack->x2_id_target; //Panos: change name to master_x2...
|
||||
//id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
|
||||
//id_target = ue_id;
|
||||
@@ -1128,7 +1126,6 @@ int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome;
|
||||
pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_seNBAdditionPreparation;
|
||||
//Panos: What does the criticality indicate here?
|
||||
pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject;
|
||||
pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_SeNBAdditionRequestAcknowledge;
|
||||
out = &pdu.choice.successfulOutcome.value.choice.SeNBAdditionRequestAcknowledge;
|
||||
@@ -1144,7 +1141,6 @@ int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p
|
||||
/* mandatory */
|
||||
ie = (X2AP_SeNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequestAcknowledge_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_SeNB_UE_X2AP_ID;
|
||||
//Panos: Why for the X2_HANDOVER_REQ_ACK here the criticality is ignore whereas in the specs it is reject?
|
||||
ie->criticality = X2AP_Criticality_reject;
|
||||
ie->value.present = X2AP_SeNBAdditionRequestAcknowledge_IEs__value_PR_UE_X2AP_ID_1;
|
||||
ie->value.choice.UE_X2AP_ID_1 = 0;
|
||||
@@ -1230,17 +1226,17 @@ int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*setup request message from an eNB to a gNB*/
|
||||
int x2ap_eNB_generate_ENDC_x2_setup_request(
|
||||
/*setup request message from a gNB to an eNB*/
|
||||
int x2ap_gNB_generate_ENDC_x2_setup_request(
|
||||
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p)
|
||||
{
|
||||
printf("In x2ap_eNB_generate_ENDC_x2_setup_request \n");
|
||||
X2AP_X2AP_PDU_t pdu;
|
||||
X2AP_ENDCX2SetupRequest_t *out;
|
||||
X2AP_ENDCX2SetupRequest_IEs_t *ie;
|
||||
X2AP_ENB_ENDCX2SetupReqIEs_t *ie_ENB_ENDC;
|
||||
X2AP_En_gNB_ENDCX2SetupReqIEs_t *ie_GNB_ENDC;
|
||||
X2AP_PLMN_Identity_t *plmn;
|
||||
ServedEUTRAcellsENDCX2ManagementList__Member *servedCellMember;
|
||||
ServedNRcellsENDCX2ManagementList__Member *servedCellMember;
|
||||
X2AP_SupportedSULFreqBandItem_t *SULFreqBandItem;
|
||||
|
||||
uint8_t *buffer;
|
||||
uint32_t len;
|
||||
@@ -1262,24 +1258,166 @@ int x2ap_eNB_generate_ENDC_x2_setup_request(
|
||||
ie = (X2AP_ENDCX2SetupRequest_IEs_t *)calloc(1, sizeof(X2AP_ENDCX2SetupRequest_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_InitiatingNodeType_EndcX2Setup;
|
||||
ie->value.present = X2AP_ENDCX2SetupRequest_IEs__value_PR_InitiatingNodeType_EndcX2Setup;
|
||||
ie->value.choice.InitiatingNodeType_EndcX2Setup.present = X2AP_InitiatingNodeType_EndcX2Setup_PR_init_eNB;
|
||||
ie->value.choice.InitiatingNodeType_EndcX2Setup.present = X2AP_InitiatingNodeType_EndcX2Setup_PR_init_en_gNB;
|
||||
|
||||
ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqIEs_t *)calloc(1, sizeof(X2AP_ENB_ENDCX2SetupReqIEs_t));
|
||||
ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqIEs_t *)calloc(1, sizeof(X2AP_En_gNB_ENDCX2SetupReqIEs_t));
|
||||
ie_GNB_ENDC->id = X2AP_ProtocolIE_ID_id_Globalen_gNB_ID;
|
||||
ie_GNB_ENDC->criticality = X2AP_Criticality_reject;
|
||||
ie_GNB_ENDC->value.present = X2AP_En_gNB_ENDCX2SetupReqAckIEs__value_PR_GlobalGNB_ID;
|
||||
ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.present = X2AP_GNB_ID_PR_gNB_ID;
|
||||
INT32_TO_OCTET_STRING(instance_p->eNB_id,
|
||||
&ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID);
|
||||
|
||||
X2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id,
|
||||
ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.buf[0],
|
||||
ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.buf[1],
|
||||
ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.buf[2]);
|
||||
|
||||
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
|
||||
&ie_GNB_ENDC->value.choice.GlobalGNB_ID.pLMN_Identity);
|
||||
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_en_gNB.list, ie_GNB_ENDC);
|
||||
|
||||
ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqIEs_t *)calloc(1, sizeof(X2AP_En_gNB_ENDCX2SetupReqIEs_t));
|
||||
ie_GNB_ENDC->id = X2AP_ProtocolIE_ID_id_ServedNRcellsENDCX2ManagementList;
|
||||
ie_GNB_ENDC->criticality = X2AP_Criticality_reject;
|
||||
ie_GNB_ENDC->value.present = X2AP_En_gNB_ENDCX2SetupReqIEs__value_PR_ServedNRcellsENDCX2ManagementList;
|
||||
|
||||
{
|
||||
for (int i = 0; i<instance_p->num_cc; i++){
|
||||
servedCellMember = (ServedNRcellsENDCX2ManagementList__Member *)calloc(1,sizeof(ServedNRcellsENDCX2ManagementList__Member));
|
||||
{
|
||||
servedCellMember->servedNRCellInfo.nrpCI = instance_p->Nid_cell[i];
|
||||
|
||||
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
|
||||
&servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity);
|
||||
NR_CELL_ID_TO_BIT_STRING(instance_p->eNB_id,
|
||||
&servedCellMember->servedNRCellInfo.nrCellID.nRcellIdentifier);
|
||||
servedCellMember->servedNRCellInfo.fiveGS_TAC = calloc(1, sizeof(X2AP_FiveGS_TAC_t));
|
||||
if (servedCellMember->servedNRCellInfo.fiveGS_TAC == NULL)
|
||||
exit(1);
|
||||
NR_FIVEGS_TAC_ID_TO_BIT_STRING(instance_p->tac, servedCellMember->servedNRCellInfo.fiveGS_TAC);
|
||||
|
||||
X2AP_INFO("TAC: %d -> %02x%02x%02x\n", instance_p->tac,
|
||||
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[0],
|
||||
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[1],
|
||||
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[2]);
|
||||
|
||||
plmn = (X2AP_PLMN_Identity_t *)calloc(1,sizeof(X2AP_PLMN_Identity_t));
|
||||
{
|
||||
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn);
|
||||
ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.broadcastPLMNs.list, plmn);
|
||||
}
|
||||
|
||||
if (instance_p->frame_type[i] == TDD) {
|
||||
X2AP_FreqBandNrItem_t *freq_band;
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.present = X2AP_ServedNRCell_Information__nrModeInfo_PR_tdd;
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.nRARFCN = 0; //instance_p->tdd_nRARFCN[i];
|
||||
/* addition of Frequency Band List */
|
||||
freq_band = calloc(1, sizeof(X2AP_FreqBandNrItem_t));
|
||||
if (freq_band == NULL)
|
||||
exit(1);
|
||||
freq_band->freqBandIndicatorNr = 1; /* TODO: put correct value */
|
||||
|
||||
SULFreqBandItem = calloc(1, sizeof(X2AP_SupportedSULFreqBandItem_t));
|
||||
SULFreqBandItem->freqBandIndicatorNr=80; /* TODO: put correct value */
|
||||
ASN_SEQUENCE_ADD(&freq_band->supportedSULBandList.list, SULFreqBandItem);
|
||||
|
||||
ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.freqBandListNr, freq_band);
|
||||
switch (instance_p->N_RB_DL[i]) {
|
||||
case 50:
|
||||
//This is not correct. Just to be able to test X2 only using an eNB instead of gNB
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb51;
|
||||
break;
|
||||
case 93 :
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb93;
|
||||
break;
|
||||
case 106:
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb106;
|
||||
break;
|
||||
case 121:
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb121;
|
||||
break;
|
||||
/*More cases to be added */
|
||||
default:
|
||||
AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
AssertFatal(0,"ENDC_X2Setuprequest not supported for FDD!");
|
||||
}
|
||||
/*Don't know where to extract the value of measurementTimingConfiguration from. Set it to 0 for now */
|
||||
INT8_TO_OCTET_STRING(0, &servedCellMember->servedNRCellInfo.measurementTimingConfiguration);
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list, servedCellMember);
|
||||
}
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_en_gNB.list, ie_GNB_ENDC);
|
||||
|
||||
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
X2AP_ERROR("Failed to encode ENDC X2 setup request\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2Setup/initiatingMessage assoc_id %u", x2ap_eNB_data_p->assoc_id);
|
||||
|
||||
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int x2ap_eNB_generate_ENDC_x2_setup_response(
|
||||
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p)
|
||||
{
|
||||
X2AP_X2AP_PDU_t pdu;
|
||||
X2AP_ENDCX2SetupResponse_t *out;
|
||||
X2AP_ENDCX2SetupResponse_IEs_t *ie;
|
||||
X2AP_ENB_ENDCX2SetupReqAckIEs_t *ie_ENB_ENDC;
|
||||
X2AP_PLMN_Identity_t *plmn;
|
||||
ServedEUTRAcellsENDCX2ManagementList__Member *servedCellMember;
|
||||
|
||||
uint8_t *buffer;
|
||||
uint32_t len;
|
||||
int ret = 0;
|
||||
|
||||
DevAssert(instance_p != NULL);
|
||||
DevAssert(x2ap_eNB_data_p != NULL);
|
||||
|
||||
x2ap_eNB_data_p->state = X2AP_ENB_STATE_WAITING;
|
||||
|
||||
/* Prepare the X2AP message to encode */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome;
|
||||
pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_endcX2Setup;
|
||||
pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject;
|
||||
pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_ENDCX2SetupResponse;
|
||||
out = &pdu.choice.successfulOutcome.value.choice.ENDCX2SetupResponse;
|
||||
|
||||
ie = (X2AP_ENDCX2SetupResponse_IEs_t *)calloc(1, sizeof(X2AP_ENDCX2SetupResponse_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_RespondingNodeType_EndcX2Setup;
|
||||
ie->value.present = X2AP_ENDCX2SetupResponse_IEs__value_PR_RespondingNodeType_EndcX2Setup;
|
||||
ie->value.choice.RespondingNodeType_EndcX2Setup.present = X2AP_RespondingNodeType_EndcX2Setup_PR_respond_eNB;
|
||||
|
||||
ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqAckIEs_t *)calloc(1, sizeof(X2AP_ENB_ENDCX2SetupReqAckIEs_t));
|
||||
ie_ENB_ENDC->id = X2AP_ProtocolIE_ID_id_GlobalENB_ID;
|
||||
ie_ENB_ENDC->criticality = X2AP_Criticality_reject;
|
||||
ie_ENB_ENDC->value.present = X2AP_ENB_ENDCX2SetupReqIEs__value_PR_GlobalENB_ID;
|
||||
ie_ENB_ENDC->value.present = X2AP_ENB_ENDCX2SetupReqAckIEs__value_PR_GlobalENB_ID;
|
||||
ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.present = X2AP_ENB_ID_PR_macro_eNB_ID;
|
||||
MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id,
|
||||
&ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID);
|
||||
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
|
||||
&ie_ENB_ENDC->value.choice.GlobalENB_ID.pLMN_Identity);
|
||||
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list, ie_ENB_ENDC);
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_eNB.list, ie_ENB_ENDC);
|
||||
|
||||
ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqIEs_t *)calloc(1, sizeof(X2AP_ENB_ENDCX2SetupReqIEs_t));
|
||||
ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqAckIEs_t *)calloc(1, sizeof(X2AP_ENB_ENDCX2SetupReqAckIEs_t));
|
||||
ie_ENB_ENDC->id = X2AP_ProtocolIE_ID_id_ServedEUTRAcellsENDCX2ManagementList;
|
||||
ie_ENB_ENDC->criticality = X2AP_Criticality_reject;
|
||||
ie_ENB_ENDC->value.present = X2AP_ENB_ENDCX2SetupReqIEs__value_PR_ServedEUTRAcellsENDCX2ManagementList;
|
||||
ie_ENB_ENDC->value.present = X2AP_ENB_ENDCX2SetupReqAckIEs__value_PR_ServedEUTRAcellsENDCX2ManagementList;
|
||||
|
||||
{
|
||||
for (int i = 0; i<instance_p->num_cc; i++){
|
||||
@@ -1299,11 +1437,11 @@ int x2ap_eNB_generate_ENDC_x2_setup_request(
|
||||
ASN_SEQUENCE_ADD(&servedCellMember->servedEUTRACellInfo.broadcastPLMNs.list, plmn);
|
||||
}
|
||||
|
||||
if (instance_p->frame_type[i] == FDD) {
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_fDD;
|
||||
if (instance_p->frame_type[i] == FDD) {
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_fDD;
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i];
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i];
|
||||
switch (instance_p->N_RB_DL[i]) {
|
||||
switch (instance_p->N_RB_DL[i]) {
|
||||
case 6:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6;
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6;
|
||||
@@ -1334,177 +1472,13 @@ int x2ap_eNB_generate_ENDC_x2_setup_request(
|
||||
}
|
||||
}
|
||||
else {
|
||||
AssertFatal(0,"X2Setuprequest not supported for TDD!");
|
||||
AssertFatal(0,"X2Setupresponse not supported for TDD!");
|
||||
}
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list, servedCellMember);
|
||||
}
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list, ie_ENB_ENDC);
|
||||
|
||||
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
X2AP_ERROR("Failed to encode ENDC X2 setup request\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2Setup/initiatingMessage assoc_id %u", x2ap_eNB_data_p->assoc_id);
|
||||
|
||||
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*setup request message from an eNB to a gNB*/
|
||||
int x2ap_gNB_generate_ENDC_x2_setup_response(
|
||||
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p)
|
||||
{
|
||||
X2AP_INFO("In x2ap_gNB_generate_ENDC_x2_setup_response ()!\n");
|
||||
X2AP_X2AP_PDU_t pdu;
|
||||
X2AP_ENDCX2SetupResponse_t *out;
|
||||
X2AP_ENDCX2SetupResponse_IEs_t *ie;
|
||||
X2AP_En_gNB_ENDCX2SetupReqAckIEs_t *ie_GNB_ENDC;
|
||||
X2AP_PLMN_Identity_t *plmn;
|
||||
ServedNRcellsENDCX2ManagementList__Member *servedCellMember;
|
||||
|
||||
uint8_t *buffer;
|
||||
uint32_t len;
|
||||
int ret = 0;
|
||||
|
||||
DevAssert(instance_p != NULL);
|
||||
DevAssert(x2ap_eNB_data_p != NULL);
|
||||
|
||||
x2ap_eNB_data_p->state = X2AP_ENB_STATE_WAITING;
|
||||
|
||||
/* Prepare the X2AP message to encode */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome;
|
||||
pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_endcX2Setup;
|
||||
pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject;
|
||||
pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_ENDCX2SetupResponse;
|
||||
out = &pdu.choice.successfulOutcome.value.choice.ENDCX2SetupResponse;
|
||||
|
||||
ie = (X2AP_ENDCX2SetupResponse_IEs_t *)calloc(1, sizeof(X2AP_ENDCX2SetupResponse_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_RespondingNodeType_EndcX2Setup;
|
||||
ie->value.present = X2AP_ENDCX2SetupResponse_IEs__value_PR_RespondingNodeType_EndcX2Setup;
|
||||
ie->value.choice.RespondingNodeType_EndcX2Setup.present = X2AP_RespondingNodeType_EndcX2Setup_PR_respond_en_gNB;
|
||||
|
||||
ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqAckIEs_t *)calloc(1, sizeof(X2AP_En_gNB_ENDCX2SetupReqAckIEs_t));
|
||||
ie_GNB_ENDC->id = X2AP_ProtocolIE_ID_id_Globalen_gNB_ID;
|
||||
ie_GNB_ENDC->criticality = X2AP_Criticality_reject;
|
||||
ie_GNB_ENDC->value.present = X2AP_En_gNB_ENDCX2SetupReqAckIEs__value_PR_GlobalGNB_ID;
|
||||
ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.present = X2AP_GNB_ID_PR_gNB_ID;
|
||||
|
||||
INT32_TO_OCTET_STRING(instance_p->eNB_id,
|
||||
&ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID);
|
||||
|
||||
X2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id,
|
||||
ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.buf[0],
|
||||
ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.buf[1],
|
||||
ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.buf[2]);
|
||||
|
||||
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
|
||||
&ie_GNB_ENDC->value.choice.GlobalGNB_ID.pLMN_Identity);
|
||||
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_en_gNB.list, ie_GNB_ENDC);
|
||||
|
||||
ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqAckIEs_t *)calloc(1, sizeof(X2AP_En_gNB_ENDCX2SetupReqAckIEs_t));
|
||||
ie_GNB_ENDC->id = X2AP_ProtocolIE_ID_id_ServedNRcellsENDCX2ManagementList;
|
||||
ie_GNB_ENDC->criticality = X2AP_Criticality_reject;
|
||||
ie_GNB_ENDC->value.present = X2AP_En_gNB_ENDCX2SetupReqAckIEs__value_PR_ServedNRcellsENDCX2ManagementList;
|
||||
|
||||
{
|
||||
for (int i = 0; i<instance_p->num_cc; i++){
|
||||
servedCellMember = (ServedNRcellsENDCX2ManagementList__Member *)calloc(1,sizeof(ServedNRcellsENDCX2ManagementList__Member));
|
||||
{
|
||||
servedCellMember->servedNRCellInfo.nrpCI = instance_p->Nid_cell[i];
|
||||
|
||||
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
|
||||
&servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity);
|
||||
NR_CELL_ID_TO_BIT_STRING(instance_p->eNB_id,
|
||||
&servedCellMember->servedNRCellInfo.nrCellID.nRcellIdentifier);
|
||||
servedCellMember->servedNRCellInfo.fiveGS_TAC = calloc(1, sizeof(X2AP_FiveGS_TAC_t));
|
||||
if (servedCellMember->servedNRCellInfo.fiveGS_TAC == NULL)
|
||||
exit(1);
|
||||
NR_FIVEGS_TAC_ID_TO_BIT_STRING(instance_p->tac, servedCellMember->servedNRCellInfo.fiveGS_TAC);
|
||||
|
||||
X2AP_INFO("TAC: %d -> %02x%02x%02x\n", instance_p->tac,
|
||||
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[0],
|
||||
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[1],
|
||||
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[2]);
|
||||
|
||||
plmn = (X2AP_PLMN_Identity_t *)calloc(1,sizeof(X2AP_PLMN_Identity_t));
|
||||
{
|
||||
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn);
|
||||
ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.broadcastPLMNs.list, plmn);
|
||||
}
|
||||
|
||||
if (instance_p->frame_type[i] == TDD) { // Panos: Remember to change that to TDD
|
||||
X2AP_FreqBandNrItem_t *freq_band;
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.present = X2AP_ServedNRCell_Information__nrModeInfo_PR_tdd;
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.nRARFCN = 0; //instance_p->tdd_nRARFCN[i];
|
||||
|
||||
/* addition of Frequency Band List */
|
||||
freq_band = calloc(1, sizeof(X2AP_FreqBandNrItem_t));
|
||||
if (freq_band == NULL)
|
||||
exit(1);
|
||||
freq_band->freqBandIndicatorNr = 1; /* TODO: put correct value */
|
||||
ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.freqBandListNr, freq_band);
|
||||
|
||||
switch (instance_p->N_RB_DL[i]) {
|
||||
case 50:
|
||||
//This is not correct. Just to be able to test X2 only using an eNB instead of gNB
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb51;
|
||||
break;
|
||||
case 93 :
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb93;
|
||||
break;
|
||||
case 106:
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb106;
|
||||
break;
|
||||
case 121:
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb121;
|
||||
break;
|
||||
|
||||
/*More cases to be added */
|
||||
|
||||
default:
|
||||
AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
|
||||
break;
|
||||
}
|
||||
|
||||
instance_p->nr_SCS[i] = 30; // Hardcoded for now. Normally this should originate from the gNB config file
|
||||
switch (instance_p->nr_SCS[i]) {
|
||||
case 15:
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRSCS = X2AP_NRSCS_scs15;
|
||||
break;
|
||||
case 30:
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRSCS = X2AP_NRSCS_scs30;
|
||||
break;
|
||||
case 60:
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRSCS = X2AP_NRSCS_scs60;
|
||||
break;
|
||||
case 120:
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRSCS = X2AP_NRSCS_scs120;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(0,"Failed: Check value for nr_SCS");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
AssertFatal(0,"nr_X2Setupresponse not supported for FDD!");
|
||||
}
|
||||
/*Don't know where to extract the value of measurementTimingConfiguration from. Set it to 0 for now */
|
||||
INT8_TO_OCTET_STRING(0, &servedCellMember->servedNRCellInfo.measurementTimingConfiguration);
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list, servedCellMember);
|
||||
}
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_en_gNB.list, ie_GNB_ENDC);
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_eNB.list, ie_ENB_ENDC);
|
||||
|
||||
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
@@ -1521,3 +1495,360 @@ int x2ap_gNB_generate_ENDC_x2_setup_response(
|
||||
return ret;
|
||||
}
|
||||
|
||||
int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(
|
||||
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id)
|
||||
{
|
||||
X2AP_X2AP_PDU_t pdu;
|
||||
X2AP_SgNBAdditionRequest_t *out;
|
||||
X2AP_SgNBAdditionRequest_IEs_t *ie;
|
||||
X2AP_E_RABs_ToBeAdded_SgNBAddReq_ItemIEs_t *e_RABS_ToBeAdded_SgNBAddReq_ItemIEs;
|
||||
X2AP_E_RABs_ToBeAdded_SgNBAddReq_Item_t *e_RABS_ToBeAdded_SgNBAddReq_Item;
|
||||
|
||||
uint8_t *buffer;
|
||||
uint32_t len;
|
||||
int ret = 0;
|
||||
|
||||
// Currently hardcoded (dummy) values filling the fields of SgNB_addition_request message. To be substituted
|
||||
// with values coming from RRC.
|
||||
uint16_t nRencryptionAlgorithms = 0;
|
||||
uint16_t nRintegrityProtectionAlgorithms = 0;
|
||||
uint8_t SgNBSecurityKey[32] = { 0 };
|
||||
int uEaggregateMaximumBitRateDownlink = 100000000;
|
||||
int uEaggregateMaximumBitRateUplink = 100000000;
|
||||
int e_rabs_tobeadded = 1;
|
||||
int e_RAB_ID = 1;
|
||||
int drb_ID = 2;
|
||||
long int pDCPatSgNB = X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present;
|
||||
long int mCGresources = X2AP_EN_DC_ResourceConfiguration__mCGresources_not_present;
|
||||
long int sCGresources = X2AP_EN_DC_ResourceConfiguration__sCGresources_not_present;
|
||||
long qCI = 1;
|
||||
X2AP_Pre_emptionCapability_t pre_emptionCapability = X2AP_Pre_emptionCapability_shall_not_trigger_pre_emption;
|
||||
X2AP_Pre_emptionVulnerability_t pre_emptionVulnerability = X2AP_Pre_emptionVulnerability_not_pre_emptable;
|
||||
priority_level_t priority_level = PRIORITY_LEVEL_NO_PRIORITY;
|
||||
e_rab_tobe_added_t e_MCG_rabs_tobeadded;
|
||||
e_MCG_rabs_tobeadded.gtp_teid = 0;
|
||||
e_MCG_rabs_tobeadded.eNB_addr.length = 24;
|
||||
uint8_t buf[20] = { 0 };
|
||||
memcpy(e_MCG_rabs_tobeadded.eNB_addr.buffer, buf, 20*sizeof(uint8_t));
|
||||
|
||||
FILE *fd;
|
||||
fd = fopen("../../../executables/uecap.raw","r");
|
||||
if (fd != NULL) {
|
||||
OCTET_STRING_t CG_Config_Info;
|
||||
CG_Config_Info.size = 4096;
|
||||
CG_Config_Info.buf = (uint8_t *)calloc(4096, sizeof(uint8_t));
|
||||
int msg_len=fread(CG_Config_Info.buf,1,CG_Config_Info.size,fd);
|
||||
CG_Config_Info.size = msg_len;
|
||||
|
||||
/*char buffer[4096];
|
||||
int msg_len=fread(buffer,1,4096,fd);*/
|
||||
LOG_I(RRC,"Read in %d bytes for uecap\n",msg_len);
|
||||
|
||||
|
||||
/*OCTET_STRING_t CG_Config_Info;
|
||||
CG_Config_Info.size = 4096;
|
||||
CG_Config_Info.buf = (uint8_t *)calloc(4096, sizeof(uint8_t));*/
|
||||
|
||||
|
||||
DevAssert(instance_p != NULL);
|
||||
DevAssert(x2ap_eNB_data_p != NULL);
|
||||
|
||||
x2ap_eNB_data_p->state = X2AP_ENB_STATE_WAITING;
|
||||
|
||||
|
||||
|
||||
/* Prepare the X2AP message to encode */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage;
|
||||
pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_sgNBAdditionPreparation;
|
||||
pdu.choice.initiatingMessage.criticality = X2AP_Criticality_reject;
|
||||
pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_SgNBAdditionRequest;
|
||||
out = &pdu.choice.initiatingMessage.value.choice.SgNBAdditionRequest;
|
||||
|
||||
ie = (X2AP_SgNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequest_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID; //Not sure about that
|
||||
ie->criticality= X2AP_Criticality_reject;
|
||||
ie->value.present = X2AP_SgNBAdditionRequest_IEs__value_PR_UE_X2AP_ID;
|
||||
ie->value.choice.UE_X2AP_ID = x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
ie = (X2AP_SgNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequest_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_NRUESecurityCapabilities;
|
||||
ie->criticality = X2AP_Criticality_reject;
|
||||
ie->value.present = X2AP_SgNBAdditionRequest_IEs__value_PR_NRUESecurityCapabilities;
|
||||
INT16_TO_BIT_STRING(nRencryptionAlgorithms, &ie->value.choice.NRUESecurityCapabilities.nRencryptionAlgorithms);
|
||||
INT16_TO_BIT_STRING(nRintegrityProtectionAlgorithms, &ie->value.choice.NRUESecurityCapabilities.nRintegrityProtectionAlgorithms);
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
ie = (X2AP_SgNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequest_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_SgNBSecurityKey;
|
||||
ie->criticality = X2AP_Criticality_reject;
|
||||
ie->value.present = X2AP_SgNBAdditionRequest_IEs__value_PR_SgNBSecurityKey;
|
||||
KENB_STAR_TO_BIT_STRING(SgNBSecurityKey, &ie->value.choice.SgNBSecurityKey);
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
ie = (X2AP_SgNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequest_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_SgNBUEAggregateMaximumBitRate;
|
||||
ie->criticality = X2AP_Criticality_reject;
|
||||
ie->value.present = X2AP_SgNBAdditionRequest_IEs__value_PR_UEAggregateMaximumBitRate;
|
||||
ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink.buf = (uint8_t *)calloc(4, sizeof(uint8_t));
|
||||
INT32_TO_BUFFER(uEaggregateMaximumBitRateDownlink, ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink.buf);
|
||||
ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink.size = 4;
|
||||
|
||||
ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateUplink.buf = (uint8_t *)calloc(4, sizeof(uint8_t));
|
||||
INT32_TO_BUFFER(uEaggregateMaximumBitRateUplink, ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateUplink.buf);
|
||||
ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateUplink.size = 4;
|
||||
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
ie = (X2AP_SgNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequest_IEs_t));
|
||||
//Not sure if id should be X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_List or X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_SgNBAddReqList
|
||||
ie->id = X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_SgNBAddReqList;
|
||||
ie->criticality = X2AP_Criticality_reject;
|
||||
ie->value.present = X2AP_SgNBAdditionRequest_IEs__value_PR_E_RABs_ToBeAdded_SgNBAddReqList;
|
||||
|
||||
for (int i=0;i<e_rabs_tobeadded;i++) {
|
||||
e_RABS_ToBeAdded_SgNBAddReq_ItemIEs = (X2AP_E_RABs_ToBeAdded_SgNBAddReq_ItemIEs_t *)calloc(1,sizeof(X2AP_E_RABs_ToBeAdded_SgNBAddReq_ItemIEs_t));
|
||||
e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->id = X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_SgNBAddReq_Item;
|
||||
e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->criticality = X2AP_Criticality_ignore;
|
||||
e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->value.present = X2AP_E_RABs_ToBeAdded_SgNBAddReq_ItemIEs__value_PR_E_RABs_ToBeAdded_SgNBAddReq_Item;
|
||||
e_RABS_ToBeAdded_SgNBAddReq_Item = &e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->value.choice.E_RABs_ToBeAdded_SgNBAddReq_Item;
|
||||
{
|
||||
e_RABS_ToBeAdded_SgNBAddReq_Item->drb_ID = drb_ID;
|
||||
e_RABS_ToBeAdded_SgNBAddReq_Item->e_RAB_ID = e_RAB_ID;
|
||||
e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.pDCPatSgNB = pDCPatSgNB;
|
||||
e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.mCGresources = mCGresources;
|
||||
e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.sCGresources = sCGresources;
|
||||
if (pDCPatSgNB == X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present){
|
||||
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.present = X2AP_E_RABs_ToBeAdded_SgNBAddReq_Item__resource_configuration_PR_sgNBPDCPpresent;
|
||||
|
||||
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.qCI = qCI;
|
||||
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability = pre_emptionCapability;
|
||||
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority. pre_emptionVulnerability = pre_emptionVulnerability;
|
||||
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = priority_level;
|
||||
|
||||
//Continue from filling the UL_GTPtunnelEndpointInformation inspired from how it is done for the HO case
|
||||
INT32_TO_OCTET_STRING(e_MCG_rabs_tobeadded.gtp_teid, &e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.gTP_TEID);
|
||||
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size = e_MCG_rabs_tobeadded.eNB_addr.length/8;
|
||||
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = e_MCG_rabs_tobeadded.eNB_addr.length%8;
|
||||
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf =
|
||||
calloc(1, e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size);
|
||||
|
||||
memcpy (e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf,
|
||||
e_MCG_rabs_tobeadded.eNB_addr.buffer,
|
||||
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size);
|
||||
}
|
||||
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_ToBeAdded_SgNBAddReqList.list, e_RABS_ToBeAdded_SgNBAddReq_ItemIEs);
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
ie = (X2AP_SgNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequest_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_MeNBtoSgNBContainer;
|
||||
ie->criticality = X2AP_Criticality_reject;
|
||||
ie->value.present = X2AP_SgNBAdditionRequest_IEs__value_PR_MeNBtoSgNBContainer;
|
||||
ie->value.choice.MeNBtoSgNBContainer.buf = (uint8_t *)calloc(CG_Config_Info.size, sizeof(uint8_t));
|
||||
memcpy(ie->value.choice.MeNBtoSgNBContainer.buf, CG_Config_Info.buf, CG_Config_Info.size);
|
||||
ie->value.choice.MeNBtoSgNBContainer.size = CG_Config_Info.size; //4096;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
X2AP_ERROR("Failed to encode ENDC X2 SgNB_addition request message\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2Setup/initiatingMessage assoc_id %u", x2ap_eNB_data_p->assoc_id);
|
||||
|
||||
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0);
|
||||
fclose(fd);
|
||||
}
|
||||
else {
|
||||
LOG_I(RRC, "uecap.raw file could not be opened... \n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
|
||||
x2ap_ENDC_sgnb_addition_req_ACK_t *x2ap_sgnb_addition_req_ACK, int ue_id)
|
||||
{
|
||||
|
||||
X2AP_X2AP_PDU_t pdu;
|
||||
X2AP_SgNBAdditionRequestAcknowledge_t *out;
|
||||
X2AP_SgNBAdditionRequestAcknowledge_IEs_t *ie;
|
||||
X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs_t *e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs;
|
||||
X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_t *e_RABS_AdmittedToBeAdded_SgNBAddReq_Item;
|
||||
|
||||
uint8_t *buffer;
|
||||
uint32_t len;
|
||||
int ret = 0;
|
||||
int MeNB_UE_X2AP_id = ue_id;
|
||||
int SgNB_UE_X2AP_id = 0;
|
||||
|
||||
// Currently hardcoded (dummy) values filling the fields of SgNB_addition_request message. To be substituted
|
||||
// with values coming from RRC.
|
||||
uint16_t nRencryptionAlgorithms = 0;
|
||||
uint16_t nRintegrityProtectionAlgorithms = 0;
|
||||
uint8_t SgNBSecurityKey[32] = { 0 };
|
||||
int uEaggregateMaximumBitRateDownlink = 100000000;
|
||||
int uEaggregateMaximumBitRateUplink = 100000000;
|
||||
int e_rabs_admitted_tobeadded = 1;
|
||||
int e_RAB_ID = 1;
|
||||
long int pDCPatSgNB = X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present;
|
||||
long int mCGresources = X2AP_EN_DC_ResourceConfiguration__mCGresources_not_present;
|
||||
long int sCGresources = X2AP_EN_DC_ResourceConfiguration__sCGresources_not_present;
|
||||
e_rab_setup_t e_SCG_rabs_tobeadded;
|
||||
e_SCG_rabs_tobeadded.gtp_teid = 0;
|
||||
e_SCG_rabs_tobeadded.eNB_addr.length = 24;
|
||||
uint8_t buf[20] = { 0 };
|
||||
memcpy(e_SCG_rabs_tobeadded.eNB_addr.buffer, buf, 20*sizeof(uint8_t));
|
||||
|
||||
DevAssert(instance_p != NULL);
|
||||
DevAssert(x2ap_eNB_data_p != NULL);
|
||||
|
||||
x2ap_eNB_data_p->state = X2AP_ENB_STATE_WAITING;
|
||||
|
||||
// Prepare the X2AP message to encode
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome;
|
||||
pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_sgNBAdditionPreparation;
|
||||
pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject;
|
||||
pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_SgNBAdditionRequestAcknowledge;
|
||||
out = &pdu.choice.successfulOutcome.value.choice.SgNBAdditionRequestAcknowledge;
|
||||
|
||||
// MeNB_UE_X2AP_id
|
||||
ie = (X2AP_SgNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequestAcknowledge_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
|
||||
ie->criticality= X2AP_Criticality_reject;
|
||||
ie->value.present = X2AP_SgNBAdditionRequestAcknowledge_IEs__value_PR_UE_X2AP_ID;
|
||||
ie->value.choice.UE_X2AP_ID = MeNB_UE_X2AP_id; //x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
// SgNB_UE_X2AP_id
|
||||
ie = (X2AP_SgNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequestAcknowledge_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID;
|
||||
ie->criticality= X2AP_Criticality_reject;
|
||||
ie->value.present = X2AP_SgNBAdditionRequestAcknowledge_IEs__value_PR_SgNB_UE_X2AP_ID;
|
||||
ie->value.choice.UE_X2AP_ID = SgNB_UE_X2AP_id; //x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
ie = (X2AP_SgNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequestAcknowledge_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList;
|
||||
ie->criticality = X2AP_Criticality_ignore;
|
||||
ie->value.present = X2AP_SgNBAdditionRequestAcknowledge_IEs__value_PR_E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList;
|
||||
|
||||
for (int i=0;i<e_rabs_admitted_tobeadded;i++) {
|
||||
e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs = (X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs_t *)calloc(1,sizeof(X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs_t));
|
||||
e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs->id = X2AP_ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item;
|
||||
e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs->criticality = X2AP_Criticality_ignore;
|
||||
e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs->value.present = X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs__value_PR_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item;
|
||||
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item = &e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item;
|
||||
{
|
||||
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->e_RAB_ID = e_RAB_ID;
|
||||
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.pDCPatSgNB = pDCPatSgNB;
|
||||
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.mCGresources = mCGresources;
|
||||
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.sCGresources = sCGresources;
|
||||
if (pDCPatSgNB == X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present){
|
||||
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.present = X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item__resource_configuration_PR_sgNBPDCPpresent;
|
||||
|
||||
INT32_TO_OCTET_STRING(e_SCG_rabs_tobeadded.gtp_teid, &e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.gTP_TEID);
|
||||
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size = e_SCG_rabs_tobeadded.eNB_addr.length/8;
|
||||
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = e_SCG_rabs_tobeadded.eNB_addr.length%8;
|
||||
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf =
|
||||
calloc(1, e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size);
|
||||
|
||||
memcpy (e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf,
|
||||
e_SCG_rabs_tobeadded.eNB_addr.buffer,
|
||||
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size);
|
||||
}
|
||||
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList.list, e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs);
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
ie = (X2AP_SgNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequestAcknowledge_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_SgNBtoMeNBContainer;
|
||||
ie->criticality = X2AP_Criticality_reject;
|
||||
ie->value.present = X2AP_SgNBAdditionRequestAcknowledge_IEs__value_PR_SgNBtoMeNBContainer;
|
||||
ie->value.choice.SgNBtoMeNBContainer.buf = (uint8_t *)calloc(x2ap_sgnb_addition_req_ACK->rrc_buffer_size, sizeof(uint8_t));
|
||||
memcpy(ie->value.choice.SgNBtoMeNBContainer.buf, x2ap_sgnb_addition_req_ACK->rrc_buffer, x2ap_sgnb_addition_req_ACK->rrc_buffer_size);
|
||||
ie->value.choice.SgNBtoMeNBContainer.size = x2ap_sgnb_addition_req_ACK->rrc_buffer_size; //4096;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
X2AP_ERROR("Failed to encode ENDC X2 SgNB_addition request message\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2Setup/initiatingMessage assoc_id %u", x2ap_eNB_data_p->assoc_id);
|
||||
|
||||
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int x2ap_eNB_generate_ENDC_x2_SgNB_reconfiguration_complete(
|
||||
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id, int SgNB_ue_id)
|
||||
{
|
||||
X2AP_X2AP_PDU_t pdu;
|
||||
X2AP_SgNBReconfigurationComplete_t *out;
|
||||
X2AP_SgNBReconfigurationComplete_IEs_t *ie;
|
||||
|
||||
uint8_t *buffer;
|
||||
uint32_t len;
|
||||
int ret = 0;
|
||||
|
||||
DevAssert(instance_p != NULL);
|
||||
DevAssert(x2ap_eNB_data_p != NULL);
|
||||
|
||||
x2ap_eNB_data_p->state = X2AP_ENB_STATE_WAITING;
|
||||
|
||||
|
||||
/* Prepare the X2AP message to encode */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage;
|
||||
pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_sgNBReconfigurationCompletion;
|
||||
pdu.choice.initiatingMessage.criticality = X2AP_Criticality_ignore;
|
||||
pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_SgNBReconfigurationComplete;
|
||||
out = &pdu.choice.initiatingMessage.value.choice.SgNBReconfigurationComplete;
|
||||
|
||||
ie = (X2AP_SgNBReconfigurationComplete_IEs_t *)calloc(1, sizeof(X2AP_SgNBReconfigurationComplete_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
|
||||
ie->criticality= X2AP_Criticality_reject;
|
||||
ie->value.present = X2AP_SgNBReconfigurationComplete_IEs__value_PR_UE_X2AP_ID;
|
||||
ie->value.choice.UE_X2AP_ID = ue_id; //x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
ie = (X2AP_SgNBReconfigurationComplete_IEs_t *)calloc(1, sizeof(X2AP_SgNBReconfigurationComplete_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID;
|
||||
ie->criticality = X2AP_Criticality_reject;
|
||||
ie->value.present = X2AP_SgNBReconfigurationComplete_IEs__value_PR_SgNB_UE_X2AP_ID;
|
||||
ie->value.choice.SgNB_UE_X2AP_ID = SgNB_ue_id;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
ie = (X2AP_SgNBReconfigurationComplete_IEs_t *)calloc(1, sizeof(X2AP_SgNBReconfigurationComplete_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_ResponseInformationSgNBReconfComp;
|
||||
ie->criticality = X2AP_Criticality_ignore;
|
||||
ie->value.present = X2AP_SgNBReconfigurationComplete_IEs__value_PR_ResponseInformationSgNBReconfComp;
|
||||
ie->value.choice.ResponseInformationSgNBReconfComp.present = X2AP_ResponseInformationSgNBReconfComp_PR_success_SgNBReconfComp;
|
||||
// meNBtoSgNBContainer should contain the RRCReconfigurationComplete message from the UE but in the specs 36.423(9.1.4.4) its presence is not mandatory
|
||||
ie->value.choice.ResponseInformationSgNBReconfComp.choice.success_SgNBReconfComp.meNBtoSgNBContainer = NULL;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
X2AP_ERROR("Failed to encode ENDC X2 SgNB_addition request message\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
@@ -66,8 +66,15 @@ int x2ap_eNB_generate_senb_addition_request (x2ap_eNB_instance_t *instance_p, x2
|
||||
int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
|
||||
x2ap_senb_addition_req_ack_t *x2ap_addition_req_ack);
|
||||
|
||||
int x2ap_eNB_generate_ENDC_x2_setup_request(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p);
|
||||
int x2ap_gNB_generate_ENDC_x2_setup_request(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p);
|
||||
|
||||
int x2ap_gNB_generate_ENDC_x2_setup_response( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p);
|
||||
int x2ap_eNB_generate_ENDC_x2_setup_response( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p);
|
||||
|
||||
int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id);
|
||||
|
||||
int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_ENDC_sgnb_addition_req_ACK_t *x2ap_sgnb_addition_req_ACK, int ue_id);
|
||||
|
||||
int x2ap_eNB_generate_ENDC_x2_SgNB_reconfiguration_complete(
|
||||
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id, int SgNB_ue_id);
|
||||
|
||||
#endif /* X2AP_ENB_GENERATE_MESSAGES_H_ */
|
||||
|
||||
+545
-157
@@ -103,7 +103,7 @@ int x2ap_eNB_handle_senb_addition_request_reject (instance_t instance,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu);
|
||||
|
||||
int x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance,
|
||||
int x2ap_eNB_handle_ENDC_x2_setup_request(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu);
|
||||
@@ -114,8 +114,26 @@ x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu);
|
||||
|
||||
static
|
||||
int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu);
|
||||
|
||||
/* Handlers matrix. Only eNB related procedure present here */
|
||||
static
|
||||
int x2ap_eNB_handle_ENDC_sGNB_addition_response (instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu);
|
||||
|
||||
static
|
||||
int x2ap_gNB_handle_ENDC_sGNB_reconfiguration_complete (instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu);
|
||||
|
||||
|
||||
/* Handlers matrix. Only eNB related procedure present here. Placement of callback functions according to X2AP_ProcedureCode.h */
|
||||
x2ap_message_decoded_callback x2ap_messages_callback[][3] = {
|
||||
{ x2ap_eNB_handle_handover_preparation, x2ap_eNB_handle_handover_response, 0 }, /* handoverPreparation */
|
||||
{ x2ap_eNB_handle_handover_cancel, 0, 0 }, /* handoverCancel */
|
||||
@@ -144,6 +162,8 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = {
|
||||
{ 0, 0, 0 }, /* seNBinitiatedSeNBRelease */
|
||||
{ 0, 0, 0 }, /* seNBCounterCheck */
|
||||
{ 0, 0, 0 }, /* retrieveUEContext */
|
||||
{ x2ap_gNB_handle_ENDC_sGNB_addition_request, x2ap_eNB_handle_ENDC_sGNB_addition_response, 0 }, /*X2AP_ProcedureCode_id_sgNBAdditionPreparation*/
|
||||
{ x2ap_gNB_handle_ENDC_sGNB_reconfiguration_complete, 0, 0 }, /*X2AP_ProcedureCode_id_sgNBReconfigurationCompletion*/
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
@@ -151,9 +171,7 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = {
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ x2ap_gNB_handle_ENDC_x2_setup_request, x2ap_gNB_handle_ENDC_x2_setup_response, 0 },
|
||||
{ x2ap_eNB_handle_ENDC_x2_setup_request, x2ap_gNB_handle_ENDC_x2_setup_response, 0 }, /*X2AP_ProcedureCode_id_endcX2Setup*/
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 }
|
||||
@@ -1324,7 +1342,7 @@ int x2ap_eNB_handle_senb_addition_request_reject (instance_t instance,
|
||||
}
|
||||
|
||||
int
|
||||
x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance,
|
||||
x2ap_eNB_handle_ENDC_x2_setup_request(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu)
|
||||
@@ -1332,12 +1350,12 @@ x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance,
|
||||
|
||||
X2AP_ENDCX2SetupRequest_t *x2_ENDC_SetupRequest;
|
||||
X2AP_ENDCX2SetupRequest_IEs_t *ie;
|
||||
X2AP_ENB_ENDCX2SetupReqIEs_t *ie_ENB_ENDC;
|
||||
ServedEUTRAcellsENDCX2ManagementList__Member *servedCellMember;
|
||||
X2AP_En_gNB_ENDCX2SetupReqIEs_t *ie_GNB_ENDC;
|
||||
ServedNRcellsENDCX2ManagementList__Member *servedCellMember;
|
||||
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
x2ap_eNB_data_t *x2ap_eNB_data;
|
||||
uint32_t eNB_id = 0;
|
||||
uint32_t gNB_id = 0;
|
||||
|
||||
x2ap_eNB_data = NULL;
|
||||
DevAssert (pdu != NULL);
|
||||
@@ -1372,156 +1390,11 @@ x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance,
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
} else {
|
||||
if (ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list.count > 0) {
|
||||
//Panos: Here the container parameter in X2AP_FIND_PROTOCOLIE_BY_ID should be the x2_ENDC_SetupRequest
|
||||
//message or the ie to which there are more nested information elements?
|
||||
for (int i=0; i<ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list.count;i++) {
|
||||
if (ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_en_gNB.list.count > 0) {
|
||||
|
||||
ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqIEs_t*) ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list.array[i];
|
||||
if (ie_ENB_ENDC == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
for (int i=0; i<ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_en_gNB.list.count;i++) {
|
||||
|
||||
else if (ie_ENB_ENDC->id == X2AP_ProtocolIE_ID_id_GlobalENB_ID) {
|
||||
if (ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.present == X2AP_ENB_ID_PR_home_eNB_ID) {
|
||||
// Home eNB ID = 28 bits
|
||||
uint8_t *eNB_id_buf = ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.home_eNB_ID.buf;
|
||||
if (ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 28) {
|
||||
//TODO: handle case were size != 28 -> notify ? reject ?
|
||||
}
|
||||
eNB_id = (eNB_id_buf[0] << 20) + (eNB_id_buf[1] << 12) + (eNB_id_buf[2] << 4) + ((eNB_id_buf[3] & 0xf0) >> 4);
|
||||
X2AP_DEBUG("Home eNB id: %07x\n", eNB_id);
|
||||
} else {
|
||||
// Macro eNB = 20 bits
|
||||
uint8_t *eNB_id_buf = ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf;
|
||||
if (ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 20) {
|
||||
//TODO: handle case were size != 20 -> notify ? reject ?
|
||||
}
|
||||
eNB_id = (eNB_id_buf[0] << 12) + (eNB_id_buf[1] << 4) + ((eNB_id_buf[2] & 0xf0) >> 4);
|
||||
X2AP_DEBUG("macro eNB id: %05x\n", eNB_id);
|
||||
}
|
||||
X2AP_DEBUG("Adding eNB to the list of associated eNBs\n");
|
||||
if ((x2ap_eNB_data = x2ap_is_eNB_id_in_list (eNB_id)) == NULL) {
|
||||
/*
|
||||
* eNB has not been found in list of associated eNB,
|
||||
* * * * Add it to the tail of list and initialize data
|
||||
*/
|
||||
if ((x2ap_eNB_data = x2ap_is_eNB_assoc_id_in_list (assoc_id)) == NULL) {
|
||||
/*
|
||||
* ??
|
||||
*/
|
||||
return -1;
|
||||
} else {
|
||||
x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING;
|
||||
x2ap_eNB_data->eNB_id = eNB_id;
|
||||
}
|
||||
} else {
|
||||
x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING;
|
||||
|
||||
/*
|
||||
* eNB has been found in list, consider the x2 setup request as a reset connection,
|
||||
* * * * reseting any previous UE state if sctp association is != than the previous one
|
||||
*/
|
||||
if (x2ap_eNB_data->assoc_id != assoc_id) {
|
||||
/*
|
||||
* ??: Send an overload cause...
|
||||
*/
|
||||
X2AP_ERROR("Rejecting x2 setup request as eNB id %d is already associated to an active sctp association" "Previous known: %d, new one: %d\n", eNB_id, x2ap_eNB_data->assoc_id, assoc_id);
|
||||
|
||||
// Panos: Here we should be calling an ENDC specific setup_failure function instead
|
||||
x2ap_eNB_generate_x2_setup_failure (instance,
|
||||
assoc_id,
|
||||
X2AP_Cause_PR_protocol,
|
||||
X2AP_CauseProtocol_unspecified,
|
||||
-1);
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* * TODO: call the reset procedure
|
||||
*/
|
||||
}
|
||||
}
|
||||
else if (ie_ENB_ENDC->id == X2AP_ProtocolIE_ID_id_ServedEUTRAcellsENDCX2ManagementList){
|
||||
if (ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list.count > 0) {
|
||||
x2ap_eNB_data->num_cc = ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list.count;
|
||||
for (int i=0; i<ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list.count;i++) {
|
||||
servedCellMember = (ServedEUTRAcellsENDCX2ManagementList__Member *)ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list.array[i];
|
||||
x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedEUTRACellInfo.pCI;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
X2AP_ERROR("%s %d: init_eNB list is empty \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
instance_p = x2ap_eNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
|
||||
// Panos: Here we should be calling an ENDC specific setup response function
|
||||
return x2ap_gNB_generate_ENDC_x2_setup_response(instance_p, x2ap_eNB_data);
|
||||
//return x2ap_eNB_generate_x2_setup_response(instance_p, x2ap_eNB_data);
|
||||
}
|
||||
|
||||
int
|
||||
x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu)
|
||||
{
|
||||
|
||||
X2AP_ENDCX2SetupResponse_t *x2_ENDC_SetupResponse;
|
||||
X2AP_ENDCX2SetupResponse_IEs_t *ie;
|
||||
X2AP_En_gNB_ENDCX2SetupReqAckIEs_t *ie_GNB_ENDC;
|
||||
ServedNRcellsENDCX2ManagementList__Member *servedCellMember;
|
||||
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
x2ap_eNB_data_t *x2ap_eNB_data;
|
||||
uint32_t gNB_id = 0;
|
||||
|
||||
x2ap_eNB_data = NULL;
|
||||
DevAssert (pdu != NULL);
|
||||
x2_ENDC_SetupResponse = &pdu->choice.successfulOutcome.value.choice.ENDCX2SetupResponse;
|
||||
|
||||
/*
|
||||
* We received a new valid X2 Setup Request on a stream != 0.
|
||||
* * * * This should not happen -> reject eNB x2 setup request.
|
||||
*/
|
||||
|
||||
if (stream != 0) {
|
||||
X2AP_ERROR("Received new x2 setup request on stream != 0\n");
|
||||
/*
|
||||
* Send a x2 setup failure with protocol cause unspecified
|
||||
*/
|
||||
// Panos: Here we should be calling an ENDC specific setup_failure function instead
|
||||
return x2ap_eNB_generate_x2_setup_failure (instance,
|
||||
assoc_id,
|
||||
X2AP_Cause_PR_protocol,
|
||||
X2AP_CauseProtocol_unspecified,
|
||||
-1);
|
||||
}
|
||||
|
||||
X2AP_DEBUG("Received a new X2 setup request\n");
|
||||
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_ENDCX2SetupResponse_IEs_t, ie, x2_ENDC_SetupResponse,
|
||||
X2AP_ProtocolIE_ID_id_RespondingNodeType_EndcX2Setup, true);
|
||||
|
||||
|
||||
|
||||
if (ie == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
} else {
|
||||
if (ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_en_gNB.list.count > 0) {
|
||||
//Panos: Here the container parameter in X2AP_FIND_PROTOCOLIE_BY_ID should be the x2_ENDC_SetupRequest
|
||||
//message or the ie to which there are more nested information elements?
|
||||
for (int i=0; i<ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_en_gNB.list.count;i++) {
|
||||
|
||||
ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqAckIEs_t*) ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_en_gNB.list.array[i];
|
||||
ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqIEs_t*) ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list.array[i];
|
||||
if (ie_GNB_ENDC == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
@@ -1606,6 +1479,146 @@ x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance,
|
||||
}
|
||||
}
|
||||
|
||||
instance_p = x2ap_eNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
|
||||
return x2ap_eNB_generate_ENDC_x2_setup_response(instance_p, x2ap_eNB_data);
|
||||
}
|
||||
|
||||
int
|
||||
x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu)
|
||||
{
|
||||
|
||||
X2AP_ENDCX2SetupResponse_t *x2_ENDC_SetupResponse;
|
||||
X2AP_ENDCX2SetupResponse_IEs_t *ie;
|
||||
X2AP_ENB_ENDCX2SetupReqAckIEs_t *ie_ENB_ENDC;
|
||||
ServedEUTRAcellsENDCX2ManagementList__Member *servedCellMember;
|
||||
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
x2ap_eNB_data_t *x2ap_eNB_data;
|
||||
uint32_t eNB_id = 0;
|
||||
|
||||
x2ap_eNB_data = NULL;
|
||||
DevAssert (pdu != NULL);
|
||||
x2_ENDC_SetupResponse = &pdu->choice.successfulOutcome.value.choice.ENDCX2SetupResponse;
|
||||
|
||||
/*
|
||||
* We received a new valid X2 Setup Request on a stream != 0.
|
||||
* * * * This should not happen -> reject eNB x2 setup request.
|
||||
*/
|
||||
|
||||
if (stream != 0) {
|
||||
X2AP_ERROR("Received new x2 setup request on stream != 0\n");
|
||||
/*
|
||||
* Send a x2 setup failure with protocol cause unspecified
|
||||
*/
|
||||
// Here we should be calling an ENDC specific setup_failure function instead
|
||||
return x2ap_eNB_generate_x2_setup_failure (instance,
|
||||
assoc_id,
|
||||
X2AP_Cause_PR_protocol,
|
||||
X2AP_CauseProtocol_unspecified,
|
||||
-1);
|
||||
}
|
||||
|
||||
X2AP_DEBUG("Received a new X2 setup request\n");
|
||||
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_ENDCX2SetupResponse_IEs_t, ie, x2_ENDC_SetupResponse,
|
||||
X2AP_ProtocolIE_ID_id_RespondingNodeType_EndcX2Setup, true);
|
||||
|
||||
|
||||
|
||||
if (ie == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
} else {
|
||||
if (ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_eNB.list.count > 0) {
|
||||
for (int i=0; i<ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_eNB.list.count;i++) {
|
||||
|
||||
ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqAckIEs_t*) ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_eNB.list.array[i];
|
||||
if (ie_ENB_ENDC == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
else if (ie_ENB_ENDC->id == X2AP_ProtocolIE_ID_id_GlobalENB_ID) {
|
||||
if (ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.present == X2AP_ENB_ID_PR_home_eNB_ID) {
|
||||
// Home eNB ID = 28 bits
|
||||
uint8_t *eNB_id_buf = ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.home_eNB_ID.buf;
|
||||
if (ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 28) {
|
||||
//TODO: handle case were size != 28 -> notify ? reject ?
|
||||
}
|
||||
eNB_id = (eNB_id_buf[0] << 20) + (eNB_id_buf[1] << 12) + (eNB_id_buf[2] << 4) + ((eNB_id_buf[3] & 0xf0) >> 4);
|
||||
X2AP_DEBUG("Home eNB id: %07x\n", eNB_id);
|
||||
} else {
|
||||
// Macro eNB = 20 bits
|
||||
uint8_t *eNB_id_buf = ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf;
|
||||
if (ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 20) {
|
||||
//TODO: handle case were size != 20 -> notify ? reject ?
|
||||
}
|
||||
eNB_id = (eNB_id_buf[0] << 12) + (eNB_id_buf[1] << 4) + ((eNB_id_buf[2] & 0xf0) >> 4);
|
||||
X2AP_DEBUG("macro eNB id: %05x\n", eNB_id);
|
||||
}
|
||||
X2AP_DEBUG("Adding eNB to the list of associated eNBs\n");
|
||||
if ((x2ap_eNB_data = x2ap_is_eNB_id_in_list (eNB_id)) == NULL) {
|
||||
/*
|
||||
* eNB has not been found in list of associated eNB,
|
||||
* * * * Add it to the tail of list and initialize data
|
||||
*/
|
||||
if ((x2ap_eNB_data = x2ap_is_eNB_assoc_id_in_list (assoc_id)) == NULL) {
|
||||
/*
|
||||
* ??
|
||||
*/
|
||||
return -1;
|
||||
} else {
|
||||
x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING;
|
||||
x2ap_eNB_data->eNB_id = eNB_id;
|
||||
}
|
||||
} else {
|
||||
x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING;
|
||||
|
||||
/*
|
||||
* eNB has been found in list, consider the x2 setup request as a reset connection,
|
||||
* * * * reseting any previous UE state if sctp association is != than the previous one
|
||||
*/
|
||||
if (x2ap_eNB_data->assoc_id != assoc_id) {
|
||||
/*
|
||||
* ??: Send an overload cause...
|
||||
*/
|
||||
X2AP_ERROR("Rejecting x2 setup request as eNB id %d is already associated to an active sctp association" "Previous known: %d, new one: %d\n", eNB_id, x2ap_eNB_data->assoc_id, assoc_id);
|
||||
|
||||
// Here we should be calling an ENDC specific setup_failure function instead
|
||||
x2ap_eNB_generate_x2_setup_failure (instance,
|
||||
assoc_id,
|
||||
X2AP_Cause_PR_protocol,
|
||||
X2AP_CauseProtocol_unspecified,
|
||||
-1);
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* * TODO: call the reset procedure
|
||||
*/
|
||||
}
|
||||
}
|
||||
else if (ie_ENB_ENDC->id == X2AP_ProtocolIE_ID_id_ServedEUTRAcellsENDCX2ManagementList){
|
||||
if (ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list.count > 0) {
|
||||
x2ap_eNB_data->num_cc = ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list.count;
|
||||
for (int i=0; i<ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list.count;i++) {
|
||||
servedCellMember = (ServedEUTRAcellsENDCX2ManagementList__Member *)ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list.array[i];
|
||||
x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedEUTRACellInfo.pCI;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
X2AP_ERROR("%s %d: init_eNB list is empty \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Optionaly set the target eNB name */
|
||||
|
||||
/* The association is now ready as source and target eNBs know parameters of each other.
|
||||
@@ -1622,4 +1635,379 @@ x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu)
|
||||
{
|
||||
|
||||
|
||||
X2AP_SgNBAdditionRequest_t *x2SgNBAdditionRequest;
|
||||
X2AP_SgNBAdditionRequest_IEs_t *ie;
|
||||
|
||||
X2AP_E_RABs_ToBeAdded_SgNBAddReq_ItemIEs_t *e_RABS_ToBeAdded_SgNBAddReq_ItemIEs;
|
||||
X2AP_E_RABs_ToBeAdded_SgNBAddReq_Item_t *e_RABS_ToBeAdded_SgNBAddReq_Item;
|
||||
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
x2ap_eNB_data_t *x2ap_eNB_data;
|
||||
MessageDef *msg;
|
||||
int ue_id;
|
||||
|
||||
DevAssert (pdu != NULL);
|
||||
x2SgNBAdditionRequest = &pdu->choice.initiatingMessage.value.choice.SgNBAdditionRequest;
|
||||
|
||||
/*if (stream == 0) {
|
||||
X2AP_ERROR ("Received new x2 SgNB Addition request on stream == 0\n");
|
||||
// TODO: send a x2 failure response
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
X2AP_DEBUG ("Received a new X2 SgNB Addition request\n");
|
||||
|
||||
x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0);
|
||||
DevAssert(x2ap_eNB_data != NULL);
|
||||
|
||||
X2AP_INFO("X2AP Association id: %d \n",assoc_id);
|
||||
|
||||
instance_p = x2ap_eNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
|
||||
//Allocate an ITTI X2AP_SGNB_ADDITION_REQ message instead
|
||||
msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_ADDITION_REQ);
|
||||
|
||||
/* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest,
|
||||
X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID, true);
|
||||
if (ie == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// allocate a new X2AP UE ID
|
||||
ue_id = x2ap_allocate_new_id(&instance_p->id_manager);
|
||||
if (ue_id == -1) {
|
||||
X2AP_ERROR("could not allocate a new X2AP UE ID\n");
|
||||
// TODO: cancel handover: send HO preparation failure to source eNB
|
||||
exit(1);
|
||||
}
|
||||
// rnti is unknown yet, must not be set to -1, 0 is fine
|
||||
x2ap_set_ids(&instance_p->id_manager, ue_id, 0, ie->value.choice.UE_X2AP_ID, ue_id);
|
||||
x2ap_id_set_state(&instance_p->id_manager, ue_id, X2ID_STATE_TARGET);
|
||||
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ(msg).ue_x2_id = ue_id;
|
||||
|
||||
|
||||
/* X2AP_ProtocolIE_ID_id_NRUESecurityCapabilities */
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest,
|
||||
X2AP_ProtocolIE_ID_id_NRUESecurityCapabilities, true);
|
||||
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ(msg).security_capabilities.encryption_algorithms =
|
||||
BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRencryptionAlgorithms);
|
||||
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ(msg).security_capabilities.integrity_algorithms =
|
||||
BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRintegrityProtectionAlgorithms);
|
||||
|
||||
/* X2AP_ProtocolIE_ID_id_SgNBSecurityKey */
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest,
|
||||
X2AP_ProtocolIE_ID_id_SgNBSecurityKey, true);
|
||||
|
||||
if ((ie->value.choice.SgNBSecurityKey.buf) &&
|
||||
(ie->value.choice.SgNBSecurityKey.size == 32)) {
|
||||
memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).kgnb, ie->value.choice.SgNBSecurityKey.buf, 32);
|
||||
} else {
|
||||
X2AP_WARN ("Size of eNB key star does not match the expected value\n");
|
||||
}
|
||||
|
||||
|
||||
/* X2AP_ProtocolIE_ID_id_SgNBUEAggregateMaximumBitRate */
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest,
|
||||
X2AP_ProtocolIE_ID_id_SgNBUEAggregateMaximumBitRate, true);
|
||||
|
||||
//X2AP_ENDC_SGNB_ADDITION_REQ(msg).ue_ambr.br_dl =ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink;
|
||||
//X2AP_ENDC_SGNB_ADDITION_REQ(msg).ue_ambr.br_ul = ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateUplink;
|
||||
|
||||
/* X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_SgNBAddReqList */
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest,
|
||||
X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_SgNBAddReqList, true);
|
||||
|
||||
|
||||
if (ie->value.choice.E_RABs_ToBeAdded_SgNBAddReqList.list.count > 0) {
|
||||
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded = ie->value.choice.E_RABs_ToBeAdded_SgNBAddReqList.list.count;
|
||||
|
||||
for (int i=0;i<ie->value.choice.E_RABs_ToBeAdded_SgNBAddReqList.list.count;i++) {
|
||||
e_RABS_ToBeAdded_SgNBAddReq_ItemIEs = (X2AP_E_RABs_ToBeAdded_SgNBAddReq_ItemIEs_t *) ie->value.choice.E_RABs_ToBeAdded_SgNBAddReqList.list.array[i];
|
||||
e_RABS_ToBeAdded_SgNBAddReq_Item = &e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->value.choice.E_RABs_ToBeAdded_SgNBAddReq_Item;
|
||||
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].e_rab_id = e_RABS_ToBeAdded_SgNBAddReq_Item->e_RAB_ID ;
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].drb_ID = e_RABS_ToBeAdded_SgNBAddReq_Item->drb_ID;
|
||||
if(e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.pDCPatSgNB == X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present){
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rab_param[i].qos.qci = e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.qCI;
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability = e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability;
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability = e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability;
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.priority_level = e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel;
|
||||
|
||||
memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].eNB_addr.buffer,
|
||||
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf,
|
||||
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size);
|
||||
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].eNB_addr.length =
|
||||
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size * 8 - e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.bits_unused;
|
||||
|
||||
OCTET_STRING_TO_INT32(&e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.gTP_TEID,
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].gtp_teid);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
X2AP_ERROR ("Can't decode the e_RABs_ToBeSetup_List \n");
|
||||
}
|
||||
|
||||
/* X2AP_ProtocolIE_ID_id_MeNBtoSgNBContainer */
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest,
|
||||
X2AP_ProtocolIE_ID_id_MeNBtoSgNBContainer, true);
|
||||
|
||||
X2AP_MeNBtoSgNBContainer_t *container = &ie->value.choice.MeNBtoSgNBContainer;
|
||||
|
||||
if (ie->value.choice.MeNBtoSgNBContainer.size > 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(X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer, ie->value.choice.MeNBtoSgNBContainer.buf, ie->value.choice.MeNBtoSgNBContainer.size);
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer_size = ie->value.choice.MeNBtoSgNBContainer.size;
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int x2ap_eNB_handle_ENDC_sGNB_addition_response (instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu)
|
||||
{
|
||||
|
||||
X2AP_SgNBAdditionRequestAcknowledge_t *x2SgNBAdditionRequest_ack;
|
||||
X2AP_SgNBAdditionRequestAcknowledge_IEs_t *ie;
|
||||
|
||||
X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs_t *e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs;
|
||||
X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_t *e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item;
|
||||
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
x2ap_eNB_data_t *x2ap_eNB_data;
|
||||
MessageDef *msg;
|
||||
int ue_id;
|
||||
int id_source;
|
||||
int id_target;
|
||||
int rnti;
|
||||
|
||||
DevAssert (pdu != NULL);
|
||||
x2SgNBAdditionRequest_ack = &pdu->choice.successfulOutcome.value.choice.SgNBAdditionRequestAcknowledge;
|
||||
|
||||
/*if (stream == 0) {
|
||||
X2AP_ERROR ("Received new x2 SgNB Addition request on stream == 0\n");
|
||||
// TODO: send a x2 failure response
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
X2AP_DEBUG ("Received a new X2 SgNB Addition request\n");
|
||||
|
||||
x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0);
|
||||
DevAssert(x2ap_eNB_data != NULL);
|
||||
|
||||
X2AP_INFO("X2AP Association id: %d \n",assoc_id);
|
||||
|
||||
instance_p = x2ap_eNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
|
||||
//Allocate an ITTI X2AP_SGNB_ADDITION_REQ message instead
|
||||
msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_ADDITION_REQ_ACK);
|
||||
|
||||
/* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequestAcknowledge_IEs_t, ie, x2SgNBAdditionRequest_ack,
|
||||
X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID, true);
|
||||
if (ie == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
id_source = ie->value.choice.UE_X2AP_ID;
|
||||
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).MeNB_ue_x2_id = ie->value.choice.UE_X2AP_ID;
|
||||
|
||||
|
||||
/* X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID */
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequestAcknowledge_IEs_t, ie, x2SgNBAdditionRequest_ack,
|
||||
X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID, true);
|
||||
if (ie == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
id_target = ie->value.choice.SgNB_UE_X2AP_ID;
|
||||
|
||||
ue_id = id_source;
|
||||
|
||||
if (ue_id != x2ap_find_id_from_id_source(&instance_p->id_manager, id_source)) {
|
||||
X2AP_WARN("incorrect/unknown X2AP IDs for UE (old ID %d new ID %d), ignoring sGNB addition response\n",
|
||||
id_source, id_target);
|
||||
itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rnti = x2ap_id_get_rnti(&instance_p->id_manager, ue_id);
|
||||
|
||||
/* id_target is a new information, store it */
|
||||
x2ap_set_ids(&instance_p->id_manager, ue_id, rnti, id_source, id_target);
|
||||
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rnti = rnti;
|
||||
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).SgNB_ue_x2_id = ie->value.choice.SgNB_UE_X2AP_ID;
|
||||
|
||||
/* X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_SgNBAddReqList */
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequestAcknowledge_IEs_t, ie, x2SgNBAdditionRequest_ack,
|
||||
X2AP_ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList, true);
|
||||
|
||||
if (ie == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (ie->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList.list.count > 0) {
|
||||
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).nb_e_rabs_admitted_tobeadded = ie->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList.list.count;
|
||||
|
||||
for (int i=0;i<ie->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList.list.count;i++) {
|
||||
|
||||
e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs = (X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs_t *) ie->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList.list.array[i];
|
||||
e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item = &e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item;
|
||||
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].e_rab_id = e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->e_RAB_ID ;
|
||||
if(e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->en_DC_ResourceConfiguration.pDCPatSgNB == X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present){
|
||||
|
||||
memcpy(X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].eNB_addr.buffer,
|
||||
e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf,
|
||||
e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size);
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].eNB_addr.length =
|
||||
e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size * 8 - e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused;
|
||||
|
||||
OCTET_STRING_TO_INT32(&e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.gTP_TEID,
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gtp_teid);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
X2AP_ERROR ("Can't decode the e_RABs_ToBeSetup_List \n");
|
||||
}
|
||||
|
||||
/* X2AP_ProtocolIE_ID_id_SgNBtoMeNBContainer */
|
||||
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequestAcknowledge_IEs_t, ie, x2SgNBAdditionRequest_ack,
|
||||
X2AP_ProtocolIE_ID_id_SgNBtoMeNBContainer, true);
|
||||
|
||||
if (ie == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//X2AP_MeNBtoSgNBContainer_t *container = &ie->value.choice.MeNBtoSgNBContainer;
|
||||
|
||||
if (ie->value.choice.SgNBtoMeNBContainer.size > 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(X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer, ie->value.choice.SgNBtoMeNBContainer.buf, ie->value.choice.SgNBtoMeNBContainer.size);
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = ie->value.choice.SgNBtoMeNBContainer.size;
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int x2ap_gNB_handle_ENDC_sGNB_reconfiguration_complete (instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu) {
|
||||
|
||||
X2AP_SgNBReconfigurationComplete_t *x2SgNBReconfigurationComplete;
|
||||
X2AP_SgNBReconfigurationComplete_IEs_t *ie;
|
||||
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
x2ap_eNB_data_t *x2ap_eNB_data;
|
||||
MessageDef *msg;
|
||||
int ue_id;
|
||||
|
||||
DevAssert (pdu != NULL);
|
||||
x2SgNBReconfigurationComplete = &pdu->choice.initiatingMessage.value.choice.SgNBReconfigurationComplete;
|
||||
|
||||
/*if (stream == 0) {
|
||||
X2AP_ERROR ("Received new x2 SgNB Addition request on stream == 0\n");
|
||||
// TODO: send a x2 failure response
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
X2AP_DEBUG ("Received X2 SgNB Reconfiguration complete message\n");
|
||||
|
||||
x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0);
|
||||
DevAssert(x2ap_eNB_data != NULL);
|
||||
|
||||
X2AP_INFO("X2AP Association id: %d \n",assoc_id);
|
||||
|
||||
instance_p = x2ap_eNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
|
||||
//Allocate an ITTI X2AP_SGNB_ADDITION_REQ message instead
|
||||
msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_RECONF_COMPLETE);
|
||||
|
||||
/* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReconfigurationComplete_IEs_t, ie, x2SgNBReconfigurationComplete,
|
||||
X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID, true);
|
||||
if (ie == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).MeNB_ue_x2_id = ie->value.choice.UE_X2AP_ID;
|
||||
|
||||
|
||||
/* X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID */
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReconfigurationComplete_IEs_t, ie, x2SgNBReconfigurationComplete,
|
||||
X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID, true);
|
||||
if (ie == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).SgNB_ue_x2_id = ie->value.choice.SgNB_UE_X2AP_ID;
|
||||
|
||||
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReconfigurationComplete_IEs_t, ie, x2SgNBReconfigurationComplete,
|
||||
X2AP_ProtocolIE_ID_id_ResponseInformationSgNBReconfComp, true);
|
||||
if (ie == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(ie->value.choice.ResponseInformationSgNBReconfComp.present == X2AP_ResponseInformationSgNBReconfComp_PR_success_SgNBReconfComp){
|
||||
X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).reconf_response = X2AP_RECONF_RESPONSE_SUCCESS;
|
||||
}
|
||||
else {
|
||||
X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).reconf_response = X2AP_RECONF_RESPONSE_REJECT;
|
||||
}
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -37,7 +37,8 @@
|
||||
typedef enum {
|
||||
X2ID_STATE_SOURCE_PREPARE,
|
||||
X2ID_STATE_SOURCE_OVERALL,
|
||||
X2ID_STATE_TARGET
|
||||
X2ID_STATE_TARGET,
|
||||
X2ID_STATE_NSA_PREPARE,
|
||||
} x2id_state_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -116,8 +116,14 @@ do { \
|
||||
#define INT16_TO_OCTET_STRING(x, aSN) \
|
||||
do { \
|
||||
(aSN)->buf = calloc(2, sizeof(uint8_t)); \
|
||||
(aSN)->size = 2; \
|
||||
INT16_TO_BUFFER(x, (aSN)->buf); \
|
||||
INT16_TO_BUFFER(x, ((aSN)->buf)); \
|
||||
(aSN)->size = 2; \
|
||||
} while(0)
|
||||
|
||||
#define INT16_TO_BIT_STRING(x, aSN) \
|
||||
do { \
|
||||
INT16_TO_OCTET_STRING(x, aSN); \
|
||||
(aSN)->bits_unused = 0; \
|
||||
} while(0)
|
||||
|
||||
#define INT8_TO_OCTET_STRING(x, aSN) \
|
||||
|
||||
@@ -0,0 +1,298 @@
|
||||
Active_eNBs = ( "eNB-Eurecom-LTEBox");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
eNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
eNB_ID = 0xe01;
|
||||
|
||||
cell_type = "CELL_MACRO_ENB";
|
||||
|
||||
eNB_name = "eNB-Eurecom-LTEBox";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
|
||||
plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } );
|
||||
|
||||
tr_s_preference = "local_mac"
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
component_carriers = (
|
||||
{
|
||||
node_function = "3GPP_eNODEB";
|
||||
node_timing = "synch_to_ext_device";
|
||||
node_synch_ref = 0;
|
||||
frame_type = "FDD";
|
||||
tdd_config = 3;
|
||||
tdd_config_s = 0;
|
||||
prefix_type = "NORMAL";
|
||||
eutra_band = 7;
|
||||
downlink_frequency = 2685000000L;
|
||||
uplink_frequency_offset = -120000000;
|
||||
Nid_cell = 1;
|
||||
N_RB_DL = 50;
|
||||
Nid_cell_mbsfn = 0;
|
||||
nb_antenna_ports = 1;
|
||||
nb_antennas_tx = 1;
|
||||
nb_antennas_rx = 1;
|
||||
tx_gain = 90;
|
||||
rx_gain = 125;
|
||||
pbch_repetition = "FALSE";
|
||||
prach_root = 0;
|
||||
prach_config_index = 0;
|
||||
prach_high_speed = "DISABLE";
|
||||
prach_zero_correlation = 1;
|
||||
prach_freq_offset = 2;
|
||||
pucch_delta_shift = 1;
|
||||
pucch_nRB_CQI = 0;
|
||||
pucch_nCS_AN = 0;
|
||||
pucch_n1_AN = 0;
|
||||
pdsch_referenceSignalPower = -27;
|
||||
pdsch_p_b = 0;
|
||||
pusch_n_SB = 1;
|
||||
pusch_enable64QAM = "DISABLE";
|
||||
pusch_hoppingMode = "interSubFrame";
|
||||
pusch_hoppingOffset = 0;
|
||||
pusch_groupHoppingEnabled = "ENABLE";
|
||||
pusch_groupAssignment = 0;
|
||||
pusch_sequenceHoppingEnabled = "DISABLE";
|
||||
pusch_nDMRS1 = 1;
|
||||
phich_duration = "NORMAL";
|
||||
phich_resource = "ONESIXTH";
|
||||
srs_enable = "DISABLE";
|
||||
/* srs_BandwidthConfig =;
|
||||
srs_SubframeConfig =;
|
||||
srs_ackNackST =;
|
||||
srs_MaxUpPts =;*/
|
||||
|
||||
pusch_p0_Nominal = -96;
|
||||
pusch_alpha = "AL1";
|
||||
pucch_p0_Nominal = -104;
|
||||
msg3_delta_Preamble = 6;
|
||||
pucch_deltaF_Format1 = "deltaF2";
|
||||
pucch_deltaF_Format1b = "deltaF3";
|
||||
pucch_deltaF_Format2 = "deltaF0";
|
||||
pucch_deltaF_Format2a = "deltaF0";
|
||||
pucch_deltaF_Format2b = "deltaF0";
|
||||
|
||||
rach_numberOfRA_Preambles = 64;
|
||||
rach_preamblesGroupAConfig = "DISABLE";
|
||||
/*
|
||||
rach_sizeOfRA_PreamblesGroupA = ;
|
||||
rach_messageSizeGroupA = ;
|
||||
rach_messagePowerOffsetGroupB = ;
|
||||
*/
|
||||
rach_powerRampingStep = 4;
|
||||
rach_preambleInitialReceivedTargetPower = -108;
|
||||
rach_preambleTransMax = 10;
|
||||
rach_raResponseWindowSize = 10;
|
||||
rach_macContentionResolutionTimer = 48;
|
||||
rach_maxHARQ_Msg3Tx = 4;
|
||||
|
||||
pcch_default_PagingCycle = 128;
|
||||
pcch_nB = "oneT";
|
||||
bcch_modificationPeriodCoeff = 2;
|
||||
ue_TimersAndConstants_t300 = 1000;
|
||||
ue_TimersAndConstants_t301 = 1000;
|
||||
ue_TimersAndConstants_t310 = 1000;
|
||||
ue_TimersAndConstants_t311 = 10000;
|
||||
ue_TimersAndConstants_n310 = 20;
|
||||
ue_TimersAndConstants_n311 = 1;
|
||||
ue_TransmissionMode = 1;
|
||||
|
||||
//Parameters for SIB18
|
||||
rxPool_sc_CP_Len = "normal";
|
||||
rxPool_sc_Period = "sf40";
|
||||
rxPool_data_CP_Len = "normal";
|
||||
rxPool_ResourceConfig_prb_Num = 20;
|
||||
rxPool_ResourceConfig_prb_Start = 5;
|
||||
rxPool_ResourceConfig_prb_End = 44;
|
||||
rxPool_ResourceConfig_offsetIndicator_present = "prSmall";
|
||||
rxPool_ResourceConfig_offsetIndicator_choice = 0;
|
||||
rxPool_ResourceConfig_subframeBitmap_present = "prBs40";
|
||||
rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000";
|
||||
rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5;
|
||||
rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
|
||||
/* rxPool_dataHoppingConfig_hoppingParameter = 0;
|
||||
rxPool_dataHoppingConfig_numSubbands = "ns1";
|
||||
rxPool_dataHoppingConfig_rbOffset = 0;
|
||||
rxPool_commTxResourceUC-ReqAllowed = "TRUE";
|
||||
*/
|
||||
// Parameters for SIB19
|
||||
discRxPool_cp_Len = "normal"
|
||||
discRxPool_discPeriod = "rf32"
|
||||
discRxPool_numRetx = 1;
|
||||
discRxPool_numRepetition = 2;
|
||||
discRxPool_ResourceConfig_prb_Num = 5;
|
||||
discRxPool_ResourceConfig_prb_Start = 3;
|
||||
discRxPool_ResourceConfig_prb_End = 21;
|
||||
discRxPool_ResourceConfig_offsetIndicator_present = "prSmall";
|
||||
discRxPool_ResourceConfig_offsetIndicator_choice = 0;
|
||||
discRxPool_ResourceConfig_subframeBitmap_present = "prBs40";
|
||||
discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff";
|
||||
discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5;
|
||||
discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
srb1_parameters :
|
||||
{
|
||||
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
|
||||
timer_poll_retransmit = 80;
|
||||
|
||||
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
|
||||
timer_reordering = 35;
|
||||
|
||||
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
|
||||
timer_status_prohibit = 0;
|
||||
|
||||
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
|
||||
poll_pdu = 4;
|
||||
|
||||
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
|
||||
poll_byte = 99999;
|
||||
|
||||
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
|
||||
max_retx_threshold = 4;
|
||||
}
|
||||
|
||||
# ------- SCTP definitions
|
||||
SCTP :
|
||||
{
|
||||
# Number of streams to use in input/output
|
||||
SCTP_INSTREAMS = 2;
|
||||
SCTP_OUTSTREAMS = 2;
|
||||
};
|
||||
|
||||
|
||||
////////// MME parameters:
|
||||
mme_ip_address = ( { ipv4 = "192.168.12.26";
|
||||
ipv6 = "192:168:30::17";
|
||||
active = "yes";
|
||||
preference = "ipv4";
|
||||
}
|
||||
);
|
||||
|
||||
///X2
|
||||
enable_x2 = "yes";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
ENB_INTERFACE_NAME_FOR_S1_MME = "enp0s31f6";
|
||||
ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.188/23";
|
||||
ENB_INTERFACE_NAME_FOR_S1U = "enp0s31f6";
|
||||
ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.188/23";
|
||||
ENB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
|
||||
ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.188/23";
|
||||
ENB_PORT_FOR_X2C = 36422; # Spec 36422
|
||||
};
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
DU = (
|
||||
{
|
||||
DU_INTERFACE_NAME_FOR_F1U = "lo";
|
||||
DU_IPV4_ADDRESS_FOR_F1U = "127.0.0.1/16";
|
||||
DU_PORT_FOR_F1U = 22100;
|
||||
F1_U_DU_TRANSPORT_TYPE = "TCP";
|
||||
}
|
||||
);
|
||||
|
||||
CU = (
|
||||
{
|
||||
CU_INTERFACE_NAME_FOR_F1U = "lo";
|
||||
CU_IPV4_ADDRESS_FOR_F1U = "127.0.0.1"; //Address to search the DU
|
||||
CU_PORT_FOR_F1U = 22100;
|
||||
F1_U_CU_TRANSPORT_TYPE = "TCP"; // One of TCP/UDP/SCTP
|
||||
DU_TYPE = "LTE";
|
||||
}//,
|
||||
// {
|
||||
// CU_INTERFACE_NAME_FOR_F1U = "eth0";
|
||||
// CU_IPV4_ADDRESS_FOR_F1U = "10.64.93.142"; //Address to search the DU
|
||||
// CU_PORT_FOR_F1U = 2211;
|
||||
// F1_U_CU_TRANSPORT_TYPE = "TCP"; // One of TCP/UDP/SCTP
|
||||
// DU_TYPE = "WiFi";
|
||||
// }
|
||||
);
|
||||
|
||||
CU_BALANCING = "ALL";
|
||||
|
||||
MACRLCs = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
phy_test_mode = 0;
|
||||
puSch10xSnr = 200;
|
||||
puCch10xSnr = 200;
|
||||
}
|
||||
);
|
||||
|
||||
L1s = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
}
|
||||
);
|
||||
|
||||
RUs = (
|
||||
{
|
||||
local_rf = "yes"
|
||||
nb_tx = 1
|
||||
nb_rx = 1
|
||||
att_tx = 0
|
||||
att_rx = 0;
|
||||
bands = [7];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 125;
|
||||
eNB_instances = [0];
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
NETWORK_CONTROLLER :
|
||||
{
|
||||
FLEXRAN_ENABLED = "no";
|
||||
FLEXRAN_INTERFACE_NAME = "lo";
|
||||
FLEXRAN_IPV4_ADDRESS = "127.0.0.1";
|
||||
FLEXRAN_PORT = 2210;
|
||||
FLEXRAN_CACHE = "/mnt/oai_agent_cache";
|
||||
FLEXRAN_AWAIT_RECONF = "no";
|
||||
};
|
||||
|
||||
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";
|
||||
}
|
||||
);
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level ="info";
|
||||
global_log_verbosity ="medium";
|
||||
hw_log_level ="info";
|
||||
hw_log_verbosity ="medium";
|
||||
phy_log_level ="info";
|
||||
phy_log_verbosity ="medium";
|
||||
mac_log_level ="info";
|
||||
mac_log_verbosity ="high";
|
||||
rlc_log_level ="info";
|
||||
rlc_log_verbosity ="medium";
|
||||
pdcp_log_level ="info";
|
||||
pdcp_log_verbosity ="medium";
|
||||
rrc_log_level ="info";
|
||||
rrc_log_verbosity ="medium";
|
||||
};
|
||||
@@ -0,0 +1,284 @@
|
||||
Active_gNBs = ( "gNB-Eurecom-5GNRBox");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_ID = 0xe00;
|
||||
|
||||
cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
gNB_name = "gNB-Eurecom-5GNRBox";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
|
||||
plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;});
|
||||
|
||||
tr_s_preference = "local_mac"
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
ssb_SubcarrierOffset = 0;
|
||||
pdsch_AntennaPorts = 1;
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
physCellId = 0;
|
||||
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# this is 3600 MHz + 84 PRBs@30kHz SCS (same as initial BWP)
|
||||
absoluteFrequencySSB = 642016;
|
||||
dl_frequencyBand = 78;
|
||||
# this is 3600 MHz
|
||||
dl_absoluteFrequencyPointA = 640000;
|
||||
#scs-SpecificCarrierList
|
||||
dl_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
dl_subcarrierSpacing = 1;
|
||||
dl_carrierBandwidth = 217;
|
||||
#initialDownlinkBWP
|
||||
#genericParameters
|
||||
# this is RBstart=84,L=50 (275*(L-1))+RBstart
|
||||
initialDLBWPlocationAndBandwidth = 13559;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialDLBWPsubcarrierSpacing = 1;
|
||||
#pdcch-ConfigCommon
|
||||
initialDLBWPcontrolResourceSetZero = 12;
|
||||
initialDLBWPsearchSpaceZero = 0;
|
||||
#pdsch-ConfigCommon
|
||||
#pdschTimeDomainAllocationList (up to 16 entries)
|
||||
initialDLBWPk0_0 = 0;
|
||||
#initialULBWPmappingType
|
||||
#0=typeA,1=typeB
|
||||
initialDLBWPmappingType_0 = 0;
|
||||
#this is SS=2,L=3
|
||||
initialDLBWPstartSymbolAndLength_0 = 40;
|
||||
|
||||
initialDLBWPk0_1 = 0;
|
||||
initialDLBWPmappingType_1 = 0;
|
||||
#this is SS=2,L=12
|
||||
initialDLBWPstartSymbolAndLength_1 = 53;
|
||||
|
||||
initialDLBWPk0_2 = 0;
|
||||
initialDLBWPmappingType_2 = 0;
|
||||
#this is SS=1,L=12
|
||||
initialDLBWPstartSymbolAndLength_2 = 54;
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 78;
|
||||
#scs-SpecificCarrierList
|
||||
ul_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
ul_subcarrierSpacing = 1;
|
||||
ul_carrierBandwidth = 217;
|
||||
pMax = 20;
|
||||
#initialUplinkBWP
|
||||
#genericParameters
|
||||
initialULBWPlocationAndBandwidth = 13559;
|
||||
# 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 = -118;
|
||||
#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
|
||||
#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
|
||||
#oneHalf (0..15) 4,8,12,16,...60,64
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
|
||||
#ra_ContentionResolutionTimer
|
||||
#(0..7) 8,16,24,32,40,48,56,64
|
||||
ra_ContentionResolutionTimer = 7;
|
||||
rsrp_ThresholdSSB = 19;
|
||||
#prach-RootSequenceIndex_PR
|
||||
#0 = 839, 1 = 139
|
||||
prach_RootSequenceIndex_PR = 1;
|
||||
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,
|
||||
# pusch-ConfigCommon (up to 16 elements)
|
||||
initialULBWPk2_0 = 2;
|
||||
initialULBWPmappingType_0 = 1
|
||||
# this is SS=0 L=11
|
||||
initialULBWPstartSymbolAndLength_0 = 55;
|
||||
|
||||
initialULBWPk2_1 = 2;
|
||||
initialULBWPmappingType_1 = 1;
|
||||
# this is SS=0 L=12
|
||||
initialULBWPstartSymbolAndLength_1 = 69;
|
||||
|
||||
|
||||
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 = 15;
|
||||
|
||||
# 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 = 2;
|
||||
nrofDownlinkSymbols = 1;
|
||||
nrofUplinkSlots = 7;
|
||||
nrofUplinkSymbols = 7;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
|
||||
# ------- SCTP definitions
|
||||
SCTP :
|
||||
{
|
||||
# Number of streams to use in input/output
|
||||
SCTP_INSTREAMS = 2;
|
||||
SCTP_OUTSTREAMS = 2;
|
||||
};
|
||||
|
||||
|
||||
////////// MME parameters:
|
||||
mme_ip_address = ( { ipv4 = "192.168.12.26";
|
||||
ipv6 = "192:168:30::17";
|
||||
active = "yes";
|
||||
preference = "ipv4";
|
||||
}
|
||||
);
|
||||
|
||||
///X2
|
||||
enable_x2 = "yes";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
target_enb_x2_ip_address = (
|
||||
{ ipv4 = "192.168.12.188";
|
||||
ipv6 = "192:168:30::17";
|
||||
preference = "ipv4";
|
||||
}
|
||||
);
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
GNB_INTERFACE_NAME_FOR_S1_MME = "enp0s31f6";
|
||||
GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.75/24";
|
||||
GNB_INTERFACE_NAME_FOR_S1U = "eth0";
|
||||
GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.75/24";
|
||||
GNB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
|
||||
GNB_IPV4_ADDRESS_FOR_X2C = "192.168.12.75/23";
|
||||
GNB_PORT_FOR_X2C = 36422; # Spec 36422
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
MACRLCs = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
}
|
||||
);
|
||||
|
||||
L1s = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
}
|
||||
);
|
||||
|
||||
RUs = (
|
||||
{
|
||||
local_rf = "yes"
|
||||
nb_tx = 1
|
||||
nb_rx = 1
|
||||
att_tx = 0
|
||||
att_rx = 0;
|
||||
bands = [7];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 114;
|
||||
eNB_instances = [0];
|
||||
sdr_addrs = "addr=192.168.20.2,mgmt_addr=192.168.20.2";
|
||||
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_RU_L1_TRX_SPLIT";
|
||||
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
|
||||
worker_config = "WORKER_ENABLE";
|
||||
}
|
||||
);
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level ="info";
|
||||
global_log_verbosity ="medium";
|
||||
hw_log_level ="info";
|
||||
hw_log_verbosity ="medium";
|
||||
phy_log_level ="info";
|
||||
phy_log_verbosity ="medium";
|
||||
mac_log_level ="info";
|
||||
mac_log_verbosity ="high";
|
||||
rlc_log_level ="info";
|
||||
rlc_log_verbosity ="medium";
|
||||
pdcp_log_level ="info";
|
||||
pdcp_log_verbosity ="medium";
|
||||
rrc_log_level ="info";
|
||||
rrc_log_verbosity ="medium";
|
||||
};
|
||||
@@ -198,15 +198,29 @@ gNBs =
|
||||
preference = "ipv4";
|
||||
}
|
||||
);
|
||||
|
||||
///X2
|
||||
enable_x2 = "yes";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
target_enb_x2_ip_address = (
|
||||
{ ipv4 = "192.168.12.108";
|
||||
ipv6 = "192:168:30::17";
|
||||
preference = "ipv4";
|
||||
}
|
||||
);
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
GNB_INTERFACE_NAME_FOR_S1_MME = "eth0";
|
||||
GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24";
|
||||
GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.188/24";
|
||||
GNB_INTERFACE_NAME_FOR_S1U = "eth0";
|
||||
GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24";
|
||||
GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.188/24";
|
||||
GNB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
|
||||
GNB_IPV4_ADDRESS_FOR_X2C = "192.168.12.188/23";
|
||||
GNB_PORT_FOR_X2C = 36422; # Spec 36422
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user